<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ardan Labs on</title><link>https://www.ardanlabs.com/</link><description>Recent content in Ardan Labs on</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 24 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.ardanlabs.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Should You Learn One Programming Language or Many? A Practical Guide for Software Engineers</title><link>https://www.ardanlabs.com/news/2026/should-you-learn-one-programming-language-or-many/</link><pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2026/should-you-learn-one-programming-language-or-many/</guid><description>&lt;p&gt;Engineers frequently ask whether they should specialize deeply in a single programming language or distribute their effort across several. The question is usually framed as a strategic decision, as if long-term career success depends on selecting the correct option early. That framing is misleading. Career progression is rarely determined by language count; it is determined by how well you understand systems and how effectively you reason about trade-offs within them.&lt;/p&gt;</description></item><item><title>Ardan Labs Connect: São Paulo, Brazil 2026</title><link>https://www.ardanlabs.com/careers/ardan-labs-connect-brazil-2026/</link><pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/ardan-labs-connect-brazil-2026/</guid><description>&lt;img src="https://www.ardanlabs.com/images/careers/al-connect-sp26.jpg" alt="Ardan Labs Connect São Paulo 2026" class="hidden lg:hidden xl:block w-full rounded-lg shadow-xl border border-neutral/20" /&gt;
&lt;img src="https://www.ardanlabs.com/images/careers/al-connect-sp26-tablet.jpg" alt="Ardan Labs Connect São Paulo 2026" class="hidden md:block xl:hidden w-full rounded-lg shadow-xl border border-neutral/20" /&gt;
&lt;img src="https://www.ardanlabs.com/images/careers/al-connect-sp26-mobile.jpg" alt="Ardan Labs Connect São Paulo 2026" class="block md:hidden w-full rounded-lg shadow-xl border border-neutral/20" /&gt;
&lt;p&gt;If you have experience with Go and are interested in future opportunities with Ardan Labs, we encourage you to share your CV with us. We’re always looking for Mid-Level to Senior engineers who are passionate about Go and backend development to join projects across the globe.&lt;/p&gt;</description></item><item><title>Range-Over Functions in Go</title><link>https://www.ardanlabs.com/blog/2024/04/range-over-functions-in-go.html</link><pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/04/range-over-functions-in-go.html</guid><description>&lt;p&gt;Iteration has long been one of the more fragmented areas of Go, with developers relying on ad hoc patterns to traverse custom data structures. This article explores the range-over-functions experiment, a proposed evolution of the language that introduces a standardized iterator model while preserving Go&amp;rsquo;s familiar for range syntax. Using the new iter package and sequence abstractions, it shows how iteration logic can be expressed more clearly, flexibly, and idiomatically. Originally published in April 2024, the concepts remain highly relevant as Go continues to evolve toward more expressive yet simple language features.&lt;/p&gt;</description></item><item><title>Query Database Using Plain English</title><link>https://www.ardanlabs.com/blog/2026/02/query-database-using-plain-english/</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2026/02/query-database-using-plain-english/</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In this post you&amp;rsquo;ll see how you can create a system that allows users to query a relational database using plain English. This allows users not familiar with SQL or business intelligence systems to get insights from data.&lt;/p&gt;
&lt;h3 id="setting-up"&gt;Setting Up&lt;/h3&gt;
&lt;p&gt;If you want to follow along, you&amp;rsquo;ll need to clone the code from &lt;a href="https://github.com/353words/llm-sql"&gt;the GitHub repo&lt;/a&gt;. This will download the code, and the database file containing the data (&lt;code&gt;bikes.ddb&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: The data is from the &lt;a href="https://www.kaggle.com/datasets/jboysen/austin-bike"&gt;Austin Bike Share dataset&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Miki Tebeka at Golang-Sydney: Go Quiz</title><link>https://www.ardanlabs.com/events/miki-tebeka-golang-sydney-go-quiz/</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/miki-tebeka-golang-sydney-go-quiz/</guid><description>&lt;p&gt;Join Miki&amp;rsquo;s Go Quiz! Tune in via live stream for a night of fun and trivia at the Sydney meet-up.&lt;/p&gt;
&lt;h3 id="a-go-quiz"&gt;A Go Quiz&lt;/h3&gt;
&lt;p&gt;What will happen when you run the following code?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;timeout&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;before &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;timeout&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Millisecond&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;after&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this interactive session, &lt;strong&gt;Miki will be broadcasting live&lt;/strong&gt; to the Sydney meet-up to challenge your knowledge of Go.&lt;/p&gt;
&lt;p&gt;The format is simple but powerful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; Miki shows a specific snippet of Go code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Guess:&lt;/strong&gt; You’ll have time to analyze the code and commit to an answer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Reveal:&lt;/strong&gt; We run the code live to see the actual output.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Deep Dive:&lt;/strong&gt; We discuss why it produced that result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Research shows that making mistakes is a fantastic way to learn and retain information. We encourage you to think carefully, take a risk with your answer, and enjoy the &amp;ldquo;aha!&amp;rdquo; moments that follow.&lt;/p&gt;</description></item><item><title>How Rust, Go, and Blockchain Are Powering Modern Innovation</title><link>https://www.ardanlabs.com/news/2026/how-rust-go-and-blockchain-are-powering-modern-innovation/</link><pubDate>Wed, 28 Jan 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2026/how-rust-go-and-blockchain-are-powering-modern-innovation/</guid><description>&lt;h2 id="the-race-to-innovate"&gt;The Race to Innovate&lt;/h2&gt;
&lt;p&gt;Speed used to be an advantage. Today, it’s a baseline requirement. Teams are expected to ship quickly, scale without friction, and recover from failure without customers noticing. Whether you’re building financial infrastructure, cloud services, or global networks, the margin for error has narrowed considerably.&lt;/p&gt;
&lt;p&gt;At the same time, systems are growing more complex. Distributed architectures are the norm. Data volumes continue to rise. Security threats evolve faster than patch cycles. Innovation, then, is no longer just about velocity. It’s about building software that can hold up under sustained pressure.&lt;/p&gt;</description></item><item><title>Kubernetes Memory Limits and Go</title><link>https://www.ardanlabs.com/blog/2024/02/kubernetes-memory-limits-go.html</link><pubDate>Tue, 27 Jan 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/02/kubernetes-memory-limits-go.html</guid><description>&lt;p&gt;Kubernetes memory limits introduce a subtle but critical interaction with the Go runtime that can determine whether a service runs efficiently or fails under load. This article explores how Go manages memory under normal conditions and what changes when Kubernetes enforces hard memory constraints. Using controlled load testing, it shows why Go is generally excellent at self regulating memory, how OOM events emerge once limits are imposed, and how tools like GOMEMLIMIT can be used to align the runtime with container boundaries. Originally published in July 2024, the guidance remains highly relevant for teams running Go services in containerized environments where stability and throughput are tightly coupled to memory configuration.&lt;/p&gt;</description></item><item><title>Everything You Wanted to Ask About Rust – Answered by Herbert Wolverson</title><link>https://www.ardanlabs.com/blog/2026/01/everything-you-wanted-to-ask-about-rust-answered-by-herbert-wolverson/</link><pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2026/01/everything-you-wanted-to-ask-about-rust-answered-by-herbert-wolverson/</guid><description>&lt;p&gt;In a recent livestream with JetBrains, Vitaly Bragilevsky sat down with Herbert Wolverson, our Lead Rust Consultant and Instructor here at Ardan Labs, to talk about everything Rust developers – beginners and pros alike – are curious about.&lt;/p&gt;
&lt;p&gt;Watch the full livestream replay on the Ardan Labs Channel and check out the &lt;a href="https://github.com/thebracket/JetBrainsWinter"&gt;GitHub repo&lt;/a&gt; with Herbert’s prepared answers and code samples. Below is a short summary of the 23 questions that were covered during the livestream.&lt;/p&gt;</description></item><item><title>Build, Connect, Grow: Ardan Labs’ 2025 in Review</title><link>https://www.ardanlabs.com/news/2025/ardan-labs-2025-in-review/</link><pubDate>Mon, 29 Dec 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/ardan-labs-2025-in-review/</guid><description>&lt;p&gt;Funny how fast a year moves when you are deep in code. One moment you are shipping a small improvement, the next you are looking back on a year shaped by releases, milestones, and conversations that influenced how developers learned, connected, and grew along the way.&lt;/p&gt;
&lt;p&gt;At Ardan Labs, 2025 was defined by momentum. We expanded how engineers learn &lt;a href="https://www.ardanlabs.com/go-services/"&gt;Go&lt;/a&gt;, &lt;a href="https://www.ardanlabs.com/rust-services"&gt;Rust&lt;/a&gt;, and &lt;a href="https://www.ardanlabs.com/k8s-services"&gt;Kubernetes&lt;/a&gt;, introduced clearer paths for skill validation, strengthened our live education offerings, and continued building a global community grounded in craftsmanship.&lt;/p&gt;</description></item><item><title>ArdanLabs Connect 2026</title><link>https://www.ardanlabs.com/events/ardan-labs-connect-2026/</link><pubDate>Thu, 18 Dec 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/ardan-labs-connect-2026/</guid><description>&lt;h2 id="agenda"&gt;Agenda&lt;/h2&gt;
&lt;p&gt;It is with great pleasure that we announce the 1st edition of Ardan Labs Connect in Brazil, which will take place on March 4th and 5th (Wednesday and Thursday) in São Paulo, SP. This is a two-day, in-person immersion promoted by Ardan Labs, taught entirely by William (Bill) Kennedy, author of the book Go in Action, covering the following topics:&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="day-1-ultimate-software-design-8h"&gt;Day 1: Ultimate Software Design (8h)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn how to develop production-grade software with Go by applying a domain- and data-oriented architecture designed to run on Kubernetes.&lt;/p&gt;</description></item><item><title>Rust Nation UK Workshop: Async - Fundamentals to Advanced</title><link>https://www.ardanlabs.com/events/20260218_rustnation_uk_workshop/</link><pubDate>Thu, 18 Dec 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20260218_rustnation_uk_workshop/</guid><description/></item><item><title>Everything You Wanted to Ask About Rust</title><link>https://www.ardanlabs.com/events/everything-you-wanted-to-ask-about-rust/</link><pubDate>Wed, 10 Dec 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/everything-you-wanted-to-ask-about-rust/</guid><description>&lt;h2 id="agenda"&gt;Agenda&lt;/h2&gt;
&lt;p&gt;In this livestream, Vitaly Bragilevsky (JetBrains) will host a Q&amp;amp;A with Herbert Wolverson from Ardan Labs. They’ll tackle the most trending and curious topics about Rust, sharing comments and ideas throughout the session.&lt;/p&gt;
&lt;p&gt;We’ll gather and ask your questions, and of course, include a few of our own. It promises to be an interactive and engaging event to wrap this year up.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="about-herbert-wolverson"&gt;&lt;strong&gt;About Herbert Wolverson:&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ardan Labs Lead Rust Instructor&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Rust is Growing Fast: What Developer Debates Reveal About It</title><link>https://www.ardanlabs.com/news/2025/rust-is-growing-fast/</link><pubDate>Thu, 04 Dec 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/rust-is-growing-fast/</guid><description>&lt;h2 id="from-systems-obscurity-to-mainstream-momentum"&gt;From Systems Obscurity to Mainstream Momentum&lt;/h2&gt;
&lt;p&gt;Rust didn’t start out as the go-to language for production teams. In its early days, it lived mostly in the world of systems purists, developers who cared deeply about memory, performance, and correctness at the lowest levels. The promise was ambitious: deliver safety and concurrency without sacrificing speed or control.&lt;/p&gt;
&lt;p&gt;Fast forward to today, and Rust looks very different. It’s running in production at startups and enterprises alike, powering everything from APIs and infrastructure to blockchain platforms and performance-critical services. What changed wasn’t just the language; it was the confidence developers gained as the ecosystem matured and real-world success stories piled up. Rust stopped being a passion project and became a business-ready tool.&lt;/p&gt;</description></item><item><title>16 Years of Go: A Programming Language Built to Last</title><link>https://www.ardanlabs.com/news/2025/16-years-of-go-a-programming-language-built-to-last/</link><pubDate>Mon, 10 Nov 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/16-years-of-go-a-programming-language-built-to-last/</guid><description>&lt;p&gt;Every November, the Go community celebrates another milestone for one of the most quietly transformative programming languages of our time.&lt;/p&gt;
&lt;p&gt;Born at Google and released to the world in &lt;strong&gt;2009&lt;/strong&gt;, Go (or Golang) was created to tackle the complexity of building software at scale, massive codebases, distributed systems, and teams working across continents. Sixteen years later, the same principles that shaped Go’s birth continue to guide its evolution: simplicity, speed, and reliability.&lt;/p&gt;</description></item><item><title>The Future We Build Together: Closing the Gender Gap in Tech</title><link>https://www.ardanlabs.com/news/2025/the-future-we-build-together-closing-the-gender-gap-in-tech/</link><pubDate>Wed, 22 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/the-future-we-build-together-closing-the-gender-gap-in-tech/</guid><description>&lt;h3 id="how-bias-culture-and-systems-shape-career-trajectoriesand-what-leaders-can-do-to-change-them"&gt;&lt;em&gt;How bias, culture, and systems shape career trajectories—and what leaders can do to change them&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;The gender gap in tech has persisted for decades. Awareness has grown, but progress often feels slow. In an industry where less than a third of technical roles are held by women, the challenges begin long before the hiring process and extend far beyond it. Women are not failing; the system is.&lt;/p&gt;
&lt;p&gt;The narrative often reads like a checklist: women are underrepresented, underpromoted, and leave the field. But what is less discussed is how much of that loss happens before a job offer is even made, and how much is shaped by the culture of belonging, or lack thereof, in the spaces they enter.&lt;/p&gt;</description></item><item><title>Getting Friendly With CPU Caches</title><link>https://www.ardanlabs.com/blog/2023/07/getting-friendly-with-cpu-caches.html</link><pubDate>Tue, 21 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/07/getting-friendly-with-cpu-caches.html</guid><description>&lt;p&gt;Understanding how your data structures interact with hardware is one of the most powerful ways to improve application performance. This blogpost explores how CPU caches influence speed and how thoughtful struct design in Go can yield massive gains. Through a real-world case study, it shows how replacing a large embedded array with a slice improved performance by more than 40 times by reducing cache misses and improving data locality. Originally published in July 2023, its lessons remain highly relevant today for developers optimizing for memory efficiency and cache-aware programming.&lt;/p&gt;</description></item><item><title>Mastering Error Handling in Rust: From Panics to this error &amp; anyhow</title><link>https://www.ardanlabs.com/events/mastering-error-handling-in-rust-from-panics-to-this-error-and-anyhow/</link><pubDate>Tue, 21 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/mastering-error-handling-in-rust-from-panics-to-this-error-and-anyhow/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, November 5th, 2025 | 12pm - 1pm EDT&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Panics, Results, and error crates—oh my! Confused about how to handle errors in Rust? You’re not alone. Rust gives you powerful tools to manage failure, but using them well takes practice.&lt;/p&gt;
&lt;p&gt;In this free webinar, Nathan Stocks will demystify when to panic, how to design clear error types, and why crates like thiserror and anyhow can make your code simpler and safer.&lt;/p&gt;</description></item><item><title>Developers Aren’t Machines: How Smart Teams Are Transforming Outsourcing</title><link>https://www.ardanlabs.com/news/2025/developers-arent-machines-how-smart-teams-are-transforming-outsourcing/</link><pubDate>Tue, 14 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/developers-arent-machines-how-smart-teams-are-transforming-outsourcing/</guid><description>&lt;p&gt;Outsourcing in software raises strong feelings in the tech world. Some see it as a fast path to scale, tapping into global talent. Others see it as a gamble, one that often costs in quality, clarity, and culture.&lt;/p&gt;
&lt;p&gt;If you hang out on Reddit, you’ll hear it all: engineers frustrated by unrealistic timelines, founders worried they’ll lose oversight, and companies scrambling to make promises they can’t keep.&lt;/p&gt;
&lt;p&gt;Here at Ardan Labs, we believe the fault lines are rarely about cost. They’re about how outsourcing is executed. And more precisely, how staff augmentation, when done right, solves many of the common mistakes.&lt;/p&gt;</description></item><item><title>How the New $100,000 H-1B Fee Impacts U.S. Companies Hiring Developers and Engineers</title><link>https://www.ardanlabs.com/news/2025/how-the-new-h-1b-fee-impacts-u.s.-companies-hiring-developers-and-engineers</link><pubDate>Tue, 07 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/how-the-new-h-1b-fee-impacts-u.s.-companies-hiring-developers-and-engineers</guid><description>&lt;p&gt;The U.S. technology sector has long relied on the H-1B visa program to bring highly skilled engineers, developers, and IT specialists into the country. For many companies, this pathway has been crucial in filling roles in cloud computing, artificial intelligence, DevOps, and cybersecurity fields where domestic talent supply often struggles to meet demand.&lt;/p&gt;
&lt;p&gt;But in September 2025, the U.S. Citizenship and Immigration Services (USCIS) announced a dramatic change that is already reshaping hiring strategies. Employers categorized as “H-1B dependent,” those with a significant percentage of H-1B workers in their workforce, will now be required to pay an additional $100,000 fee for each H-1B petition filed.&lt;/p&gt;</description></item><item><title>ARM - Corporate Training</title><link>https://www.ardanlabs.com/events/20251208_arm_miami/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20251208_arm_miami/</guid><description/></item><item><title>Delver - Corporate Training</title><link>https://www.ardanlabs.com/events/20251008_delver_corp_training/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20251008_delver_corp_training/</guid><description/></item><item><title>Eli Lilly - Corporate Training</title><link>https://www.ardanlabs.com/events/20251012_eli_lilly_corp_training/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20251012_eli_lilly_corp_training/</guid><description/></item><item><title>Golab.io</title><link>https://www.ardanlabs.com/events/20251005_golab/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20251005_golab/</guid><description/></item><item><title>Midwest AI Summit</title><link>https://www.ardanlabs.com/events/20251112_midwest_ai_summit/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20251112_midwest_ai_summit/</guid><description/></item><item><title>How Important Is Knowing Kubernetes in Today’s Job Market?</title><link>https://www.ardanlabs.com/news/2025/how-important-is-knowing-kubernetes-in-todays-job-market/</link><pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/how-important-is-knowing-kubernetes-in-todays-job-market/</guid><description>&lt;h2 id="from-google-project-to-job-market-staple"&gt;From Google Project to Job-Market Staple&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Containers are everywhere. Orchestration is no longer optional. But is Kubernetes truly a must-have skill or just another buzzword in the job hunt?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just as autocomplete reshaped how we code, Kubernetes has reshaped how we deploy. Over the past decade, it has gone from a Google project to the de-facto standard for container orchestration. Recruiters drop the word in job descriptions. Bootcamps promise to teach it in weeks. And engineers wrestle with YAML while wondering if this is really the golden ticket to landing or keeping a job.&lt;/p&gt;</description></item><item><title>Kubernetes CPU Limits and Go</title><link>https://www.ardanlabs.com/blog/2024/02/kubernetes-cpu-limits-go.html</link><pubDate>Mon, 22 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/02/kubernetes-cpu-limits-go.html</guid><description>&lt;p&gt;Kubernetes CPU limits can look straightforward on the surface, but their impact on application performance is anything but simple. This article unpacks how Go services interact with Kubernetes CPU throttling and why a seemingly harmless configuration such as setting a limit of 250m can dramatically constrain performance in production. First published in February 2024, its insights remain just as relevant today for anyone running Go applications in containerized environments and for developers who want to avoid costly slowdowns.&lt;/p&gt;</description></item><item><title>What's a Kubernetes Development Environment &amp; why you might need one</title><link>https://www.ardanlabs.com/events/whats-a-kubernetes-development-environment-and-why-you-might-need-one/</link><pubDate>Fri, 19 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/whats-a-kubernetes-development-environment-and-why-you-might-need-one/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, October 1st, 2025 | 12pm - 1pm EDT&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;To work with Kubernetes, we need a bunch of different tools. Almost everyone uses at least kubectl; and most teams use some combination of helm, kustomize, stern, k9s, skopeo, jq, gron, opentofu&amp;hellip; And of course we&amp;rsquo;ll want something to edit all that YAML, as well as our scripts, HCL files, and whatnot.&lt;/p&gt;</description></item><item><title>New Instructor Announcement - Nathan Stocks</title><link>https://www.ardanlabs.com/news/2025/new-instructor-announcement-nathan-stocks/</link><pubDate>Wed, 03 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/new-instructor-announcement-nathan-stocks/</guid><description>&lt;h2 id="meet-our-new-rust-instructor--nathan-stocks"&gt;Meet Our New Rust Instructor — Nathan Stocks&lt;/h2&gt;
&lt;p&gt;We’re excited to welcome Nathan Stocks to the Ardan Labs team as our newest Rust Instructor, joining our Rust program led by Herbert Wolverson. Nathan brings a wealth of experience and a contagious enthusiasm for Rust that inspires developers to push their skills further.&lt;/p&gt;
&lt;p&gt;With over 25 years of software development experience, he is recognized as one of the leading Rust instructors globally. He’s created multiple top-rated, best-selling courses that have reached more than 75,000 students worldwide and is also the creator of Rusty Engine, an open-source game engine built in Rust.&lt;/p&gt;</description></item><item><title>Building and Running AI, ML, and Data Science Workloads in Containers</title><link>https://www.ardanlabs.com/events/building-and-running-ai-ml-and-data-science-workloads-in-containers/</link><pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/building-and-running-ai-ml-and-data-science-workloads-in-containers/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, September 10th, 2025 | 12pm - 1pm EDT&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If we want to run AI, ML, or Data Science workloads in containers (for local development or production on Kubernetes), we need to build container images. Doing that with a Dockerfile is fairly straightforward, but is it the best method?&lt;/p&gt;
&lt;p&gt;In this talk, we&amp;rsquo;ll take a well-known speech-to-text model (Whisper) and show how to install its code and dependencies in a container. We&amp;rsquo;ll test various methods and compare the outcomes in terms of image size and build time. We&amp;rsquo;ll also show how to switch versions DRY-style (without maintaining multiple Dockerfiles!), how to leverage newer techniques like BuildKit cache mounts, and we&amp;rsquo;ll discuss other issues like the use of Alpine with Python, progressive image loading, and model loading.&lt;/p&gt;</description></item><item><title>Garbage Collection In Go : Part III - GC Pacing</title><link>https://www.ardanlabs.com/blog/2019/07/garbage-collection-in-go-part3-gcpacing.html</link><pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/07/garbage-collection-in-go-part3-gcpacing.html</guid><description>&lt;p&gt;Go’s garbage collector is designed not only to manage memory safely but also to pace itself intelligently, striking a balance between low latency and high throughput. This blogpost explores how the GC adapts its pace to workload demands, demonstrated through both sequential and concurrent program examples, and why reducing allocations per unit of work is the most effective way to lighten its load. Originally published in 2019, its core principles remain just as relevant today, offering Go developers a deeper understanding of the runtime’s adaptive behavior and confidence that the GC can find the right rhythm without extensive manual tuning.&lt;/p&gt;</description></item><item><title>Corporate Training - Custom Rust Training</title><link>https://www.ardanlabs.com/events/20250916_corp_training_custom_rust/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250916_corp_training_custom_rust/</guid><description/></item><item><title>Corporate Training - Ultimate Go</title><link>https://www.ardanlabs.com/events/20250902_corp_training_ug_miki/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250902_corp_training_ug_miki/</guid><description/></item><item><title>RustConf Workshop: Async Fundamentals</title><link>https://www.ardanlabs.com/events/20250902_rustconf_workshop_herbert/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250902_rustconf_workshop_herbert/</guid><description/></item><item><title>Ardan Labs x Deliveroo: Go, AI, &amp; Community</title><link>https://www.ardanlabs.com/events/ardan-labs-x-deliveroo-go-ai-and-community/</link><pubDate>Mon, 28 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/ardan-labs-x-deliveroo-go-ai-and-community/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Tuesday, August 12th, 2025 | 5:30pm - 9:00pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; Networking, 2x Talks, Food &amp;amp; Drinks&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; In-Person | Deliveroo HQ London&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Ardan Labs partnered with Deliveroo invites you to take the conversation further at our Go, AI, Community event designed to bring developers together for an evening of insight, inspiration, and connection.&lt;/p&gt;
&lt;p&gt;This exclusive FREE event highlighting Go &amp;amp; AI features back-to-back talks from Ardan Labs engineers Bill Kennedy and Florin Patan on the evolving roles of Go and AI in modern engineering. We’ll follow each talk with a live Q&amp;amp;A, then shift into relaxed networking over food and drinks.&lt;/p&gt;</description></item><item><title>Brains on Autocomplete: Are We Gaining Speed but Losing Mastery?</title><link>https://www.ardanlabs.com/news/2025/brains-on-autocomplete-are-we-gaining-speed-but-losing-mastery/</link><pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/brains-on-autocomplete-are-we-gaining-speed-but-losing-mastery/</guid><description>&lt;h2 id="engineers-ai-and-the-cognitive-tradeoff"&gt;Engineers, AI, and the Cognitive Tradeoff&lt;/h2&gt;
&lt;p&gt;Every generation creates tools to offload effort. In the 1960s, when electronic calculators entered classrooms, educators worried students would lose the ability to do math on their own. Why? Because the brain needs the reps. Understanding can’t be outsourced.&lt;/p&gt;
&lt;p&gt;But this wasn’t a new fear. Centuries earlier, even the abacus sparked concern. When we hand off the mechanics of thinking to a tool, what happens to the mind behind it?&lt;/p&gt;</description></item><item><title>How Embedded Engineers Reduced Fintech Transaction Delays Without Direct DB Insights</title><link>https://www.ardanlabs.com/case-studies/embedded-engineers-reduced-fintech-transaction-delays-without-direct-db-insights/</link><pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/embedded-engineers-reduced-fintech-transaction-delays-without-direct-db-insights/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-transaction-latency-was-compromising-scale"&gt;The Challenge: Transaction Latency Was Compromising Scale&lt;/h3&gt;
&lt;p&gt;As the fintech company’s platform grew, so did the demand for its database. Unfortunately, insert operations for critical payments began to slow down, affecting not just the financial layer but every system upstream.
The real kicker? Their engineering team couldn’t access detailed database metrics due to permission constraints on RDS Performance Insights. With no clear line of sight into database internals, they were flying blind.
That’s where we came in, not as external consultants, but as embedded team members ready to work shoulder-to-shoulder with their developers.&lt;/p&gt;</description></item><item><title>How Go Helped an AI Startup Scale Securely Across Cloud and Airgapped Environments</title><link>https://www.ardanlabs.com/case-studies/how-go-helped-an-ai-startup/</link><pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/how-go-helped-an-ai-startup/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-scaling-a-platform-without-slowing-down"&gt;The Challenge: Scaling a Platform Without Slowing Down&lt;/h3&gt;
&lt;p&gt;The client, a growing AI startup, was developing a powerful microservices-based platform designed to deliver real-time language model capabilities to highly regulated industries.&lt;br&gt;
From early on, they faced intense infrastructure constraints: every customer environment had to be HIPAA and SOC 2 compliant. The product needed to be deployable in cloud environments like AWS and GCP, but also in private, airgapped Kubernetes clusters where security rules were strict and connectivity was non-existent.&lt;br&gt;
The internal team was capable but stretched. They were focused on building the product and lacked the specialized infrastructure experience needed to scale the system securely and reliably across environments.&lt;br&gt;
The risk was clear: without the right expertise, deployment complexity would slow their roadmap, introduce security risks, and limit how quickly they could expand.&lt;/p&gt;</description></item><item><title>How Embedded Engineers Built a Cross-Cloud Data Platform in Go and gRPC</title><link>https://www.ardanlabs.com/case-studies/embedded-engineers-built-a-cross-cloud-data-platform-in-go-and-grpc/</link><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/embedded-engineers-built-a-cross-cloud-data-platform-in-go-and-grpc/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-distributed-data-at-enterprise-scale"&gt;The Challenge: Distributed Data at Enterprise Scale&lt;/h3&gt;
&lt;p&gt;The client’s business relied on fast, reliable access to structured and unstructured data across services, teams, and environments. But building a system that could handle ingestion, validation, and delivery in a federated cloud landscape was no small task.&lt;br&gt;
Each environment (EKS, GKE, and private K8s) introduced its own networking, storage, and identity constraints. Data had to move quickly and securely, but also remain observable, contract-driven, and testable. The internal engineering team needed support from experts who had done this before at scale.&lt;/p&gt;</description></item><item><title>How Embedded Engineers Delivered a Mission-Critical Integration Without Slowing the Roadmap</title><link>https://www.ardanlabs.com/case-studies/embedded-engineers-delivered-a-mission-critical-integration-without-slowing-the-roadmap/</link><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/embedded-engineers-delivered-a-mission-critical-integration-without-slowing-the-roadmap/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-too-much-to-build-not-enough-time"&gt;The Challenge: Too Much to Build, Not Enough Time&lt;/h3&gt;
&lt;p&gt;The company’s product roadmap was full. But the opportunity to integrate a powerful third-party API couldn’t be missed. Internally, there were no spare engineers with the time or the experience—to take it on. The internal team was delivering core roadmap items. Leadership wanted to accelerate time-to-market without disrupting momentum or reassigning internal developers.&lt;br&gt;
The API itself was non-trivial: complex schemas, evolving versions, and strict rate limits. A half-baked integration could do more harm than good. This needed to be done right and fast.&lt;/p&gt;</description></item><item><title>How Embedded Engineers Delivered Near Real-Time CRM Synchronization for Financial Advisors</title><link>https://www.ardanlabs.com/case-studies/embedded-engineers-delivered-crm-Synchronization-for-financial-advisors/</link><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/embedded-engineers-delivered-crm-Synchronization-for-financial-advisors/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-disconnected-crms-creating-chaos"&gt;The Challenge: Disconnected CRMs Creating Chaos&lt;/h3&gt;
&lt;p&gt;Each advisor used a different CRM or split leads across several. As a result, no single source of truth existed, and the lead data diverged quickly. Syncing systems manually or building per-CRM scripts proved brittle and time-consuming. Data quality suffered, workflows were delayed, and firms struggled to generate accurate reports or provide consistent client service.&lt;/p&gt;
&lt;h3 id="the-goal-deliver-real-time-synchronization-without-disruption"&gt;The Goal: Deliver Real-Time Synchronization Without Disruption&lt;/h3&gt;
&lt;p&gt;The company needed a robust and extensible system that replicated lead and client records between CRMs. It had to be real-time, handle multiple data sources, and conform to the business rules of onboarding, contact assignment, and field mapping. Importantly, it had to work within the current toolset, allowing advisors to keep using their CRM of choice without a forced migration.&lt;/p&gt;</description></item><item><title>How Rust and .NET Came Together to Power AI at Scale</title><link>https://www.ardanlabs.com/case-studies/rust-and-dot-net-to-power-ai-at-scale/</link><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/case-studies/rust-and-dot-net-to-power-ai-at-scale/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;h3 id="the-challenge-bringing-rust-performance-to-a-c-ecosystem"&gt;The Challenge: Bringing Rust Performance to a C# Ecosystem&lt;/h3&gt;
&lt;p&gt;LanceDb is engineered for speed, concurrency, and efficient semantic search—thanks to its Rust foundation and async-first architecture. However, its lack of a network service mode and primary focus on Python made it difficult to adopt for teams outside the Python ecosystem.&lt;/p&gt;
&lt;p&gt;Our client’s AI infrastructure was built in C#. Replacing their stack wasn&amp;rsquo;t an option. They needed a way to access LanceDb’s performance while keeping their .NET development model intact.&lt;/p&gt;</description></item><item><title>Garbage Collection In Go : Part II - GC Traces</title><link>https://www.ardanlabs.com/blog/2019/05/garbage-collection-in-go-part2-gctraces.html</link><pubDate>Mon, 14 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/05/garbage-collection-in-go-part2-gctraces.html</guid><description>&lt;p&gt;Originally published in 2019, this article is part two of a three-part series exploring Go’s garbage collector. Though the Go runtime has continued to evolve, the performance principles covered here remain highly relevant today. This installment focuses on practical techniques for analyzing and reducing garbage collection (GC) overhead in real-world Go applications. It walks through how to interpret GC traces using &lt;code&gt;GODEBUG=gctrace=1&lt;/code&gt; and uncover allocation hotspots with &lt;code&gt;pprof&lt;/code&gt;, with a clear message: reducing unnecessary allocations, especially in tight loops, has a direct and measurable impact on latency and throughput. Whether you&amp;rsquo;re optimizing high-performance services or just becoming GC-aware, the insights here are as applicable now as ever.&lt;/p&gt;</description></item><item><title>GopherCon US Workshop: AI-Powered Systems in Go</title><link>https://www.ardanlabs.com/events/20250826_gcus25_florin/</link><pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250826_gcus25_florin/</guid><description/></item><item><title>GopherCon US Workshop: Ultimate Go</title><link>https://www.ardanlabs.com/events/20250826_gcus25_miki/</link><pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250826_gcus25_miki/</guid><description/></item><item><title>GopherCon US Workshop: Ultimate Software Design and Engineering</title><link>https://www.ardanlabs.com/events/20250826_gcus25_bill/</link><pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250826_gcus25_bill/</guid><description/></item><item><title>Garbage Collection In Go : Part I - Semantics</title><link>https://www.ardanlabs.com/blog/2018/12/garbage-collection-in-go-part1-semantics.html</link><pubDate>Tue, 10 Jun 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/12/garbage-collection-in-go-part1-semantics.html</guid><description>&lt;p&gt;This article was originally published in 2018, yet its core insights into Go’s garbage collection model remain highly relevant for developers today. While some implementation details of Go’s runtime have evolved, the foundational concepts explored here—such as the semantics of the tri-color mark and sweep algorithm, Stop The World (STW) events, and GC trace interpretation—are still essential to understanding how Go manages memory. Whether you&amp;rsquo;re optimizing performance or deepening your knowledge of Go internals, this post continues to offer a clear and practical guide to working with the garbage collector, not against it.&lt;/p&gt;</description></item><item><title>Scaling Secure AI Infrastructure with Go and Kubernetes: A Case Study</title><link>https://www.ardanlabs.com/news/2025/scaling-secure-ai-infrastructure-with-go-and-kubernetes-a-case-study/</link><pubDate>Fri, 30 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/scaling-secure-ai-infrastructure-with-go-and-kubernetes-a-case-study/</guid><description>&lt;h2 id="executive-summary"&gt;Executive Summary&lt;/h2&gt;
&lt;p&gt;An AI startup in a highly regulated industry needed to scale fast—without compromising compliance or performance. With growing demands across cloud and airgapped environments, their infrastructure was struggling to keep up.&lt;/p&gt;
&lt;p&gt;Ardan Labs partnered with their engineering team to architect and implement a secure, scalable, and compliant deployment foundation using Go and Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; a flexible infrastructure stack that enables them to confidently deploy their AI platform anywhere.&lt;/p&gt;</description></item><item><title>JSON - The Fine Print: Part 3 - Zero vs Missing Values</title><link>https://www.ardanlabs.com/blog/2025/05/json-the-fine-print-part-3.html</link><pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2025/05/json-the-fine-print-part-3.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In &lt;a href="https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-1.html"&gt;part 1&lt;/a&gt; we took a higher level view on serialization in general and JSON in specific.
In &lt;a href="https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-2.html"&gt;part 2&lt;/a&gt; we looked at emitting JSON.&lt;/p&gt;
&lt;p&gt;In part 3, we&amp;rsquo;ll look at an issue you might encounter when consuming JSON, Zero vs NULL field values. To clarify the definition of NULL, this means the absence of value.&lt;/p&gt;
&lt;p&gt;So here is the question:&lt;/p&gt;
&lt;p&gt;Given a field in a Go struct set to its zero value, how do you know that zero value was set by the user or it&amp;rsquo;s zero because it was never provided?&lt;/p&gt;</description></item><item><title>Scheduling In Go : Part III - Concurrency</title><link>https://www.ardanlabs.com/blog/2018/12/scheduling-in-go-part3.html</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/12/scheduling-in-go-part3.html</guid><description>&lt;br /&gt;
&lt;p&gt;Although originally written in 2018, the following concepts remain essential for developers working with concurrency. This blogpost focuses on concurrency, distinguishing it from parallelism by defining it as &amp;ldquo;out of order&amp;rdquo; execution. It emphasizes the importance of understanding workload types—CPU bound (e.g., summing, sorting) and IO bound (e.g., file reading)—to assess when concurrency is appropriate. Through practical examples and benchmarks, it shows that parallelism boosts performance for CPU bound tasks, while concurrency alone benefits IO bound workloads. The post underscores that identifying workload type is key to applying concurrency effectively without added complexity.&lt;/p&gt;</description></item><item><title>Corporate Training - Ultimate Software Design and Engineering</title><link>https://www.ardanlabs.com/events/20250602_apac_corp_ultimate_software/</link><pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250602_apac_corp_ultimate_software/</guid><description/></item><item><title>Corporate Training - Ultimate Software Design and Engineering</title><link>https://www.ardanlabs.com/events/20250609_us_corp_software_design/</link><pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250609_us_corp_software_design/</guid><description/></item><item><title>Corporate Training - Ultimate Software Design and Engineering</title><link>https://www.ardanlabs.com/events/20250623_apac_corp_ultimate_software/</link><pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250623_apac_corp_ultimate_software/</guid><description/></item><item><title>Ardan Labs Launches Go and Rust Certification Exams</title><link>https://www.ardanlabs.com/news/2025/ardan-labs-launches-go-and-rust-certification-exams/</link><pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2025/ardan-labs-launches-go-and-rust-certification-exams/</guid><description>&lt;p&gt;&lt;em&gt;Miami, FL&lt;/em&gt; – Ardan Labs, a premier provider of technical training, has announced the official launch of its Go and Rust Certification Exams — a new industry benchmark designed to validate real-world programming skills and help developers stand out in a competitive tech landscape.&lt;/p&gt;
&lt;p&gt;Created in collaboration with leading technical experts, these new certifications provide a structured and respected way for developers to demonstrate expertise in two of the fastest-growing programming languages: Go and Rust. Designed with working developers in mind, the exams are proctored online and assess a developer’s ability to write clean, efficient, and production-ready code.&lt;/p&gt;</description></item><item><title>GopherCon EU Workshop: Practical Go for Developers</title><link>https://www.ardanlabs.com/events/20250616_gopherconeu_workshop_miki/</link><pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250616_gopherconeu_workshop_miki/</guid><description/></item><item><title>GopherCon EU Workshop: Ultimate Software Design with Kubernetes</title><link>https://www.ardanlabs.com/events/20250616_wopherconeu_workshop_bill/</link><pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250616_wopherconeu_workshop_bill/</guid><description/></item><item><title>GopherCon UK: Ultimate Go: Software Design with Kubernetes</title><link>https://www.ardanlabs.com/events/20250813_gopherconuk_workshop_bill/</link><pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250813_gopherconuk_workshop_bill/</guid><description/></item><item><title>GopherCon UK: AI-Powered Systems in Go</title><link>https://www.ardanlabs.com/events/20250813_gopherconuk_workshop_florin/</link><pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250813_gopherconuk_workshop_florin/</guid><description/></item><item><title>Scheduling In Go : Part II - Go Scheduler</title><link>https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html</link><pubDate>Mon, 14 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html</guid><description>&lt;br /&gt;
&lt;p&gt;This blogpost is the second installment in a three-part series exploring the mechanics and semantics of the Go scheduler. Despite being published in 2018, the content remains relevant today, as the Go scheduler&amp;rsquo;s design continues to influence the development of efficient and scalable concurrent systems.
In this post, we will go into the inner workings of the Go scheduler, discussing its components, such as the Global Run Queue (GRQ) and Local Run Queue (LRQ), and its behavior, including context switching, work stealing, and the handling of synchronous and asynchronous system calls. By understanding these concepts, developers can make informed decisions about concurrency and optimization in their Go applications.&lt;/p&gt;</description></item><item><title>GopherCon LATAM - Workshop: Ultimate Software Design &amp; Engineering Workshop</title><link>https://www.ardanlabs.com/events/20250505_gophercon_latam/</link><pubDate>Tue, 01 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250505_gophercon_latam/</guid><description/></item><item><title>Scheduling In Go : Part I - OS Scheduler</title><link>https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html</link><pubDate>Tue, 04 Mar 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html</guid><description>&lt;br /&gt;
&lt;p&gt;Although this blogpost was originally published in 2018, the concepts and principles discussed remain crucial for building efficient and performant multithreaded applications in Go now in 2025 (Go 1.24.0). As the Go ecosystem continues to evolve, understanding how the Go scheduler interacts with the operating system scheduler is more important than ever. This three-part series provides a comprehensive overview of the mechanics and semantics behind Go&amp;rsquo;s scheduling, starting with the fundamentals of the operating system scheduler.&lt;/p&gt;</description></item><item><title>Intro to Rust</title><link>https://www.ardanlabs.com/events/intro-to-rust/</link><pubDate>Tue, 11 Feb 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/intro-to-rust/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Thursday, February 27th, 2025 | 11am - 12pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.&lt;/p&gt;
&lt;p&gt;This free webinar is a fast-paced introduction to Rust concepts, features, community, and language fundamentals for professional software engineers.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll go over what makes Rust so awesome, preview some of its best features, and get you up and running fast.&lt;/p&gt;</description></item><item><title>Context Package Semantics In Go</title><link>https://www.ardanlabs.com/blog/2019/09/context-package-semantics-in-go.html</link><pubDate>Mon, 10 Feb 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/09/context-package-semantics-in-go.html</guid><description>&lt;br /&gt;
&lt;p&gt;Although first introduced in 2014, the Context package remains a crucial component of Go programming, enabling efficient management of request-scoped data, deadlines, and cancellation signals. As the Go ecosystem continues to evolve, understanding the Context package&amp;rsquo;s semantics is vital for developing reliable and maintainable software. This blogpost provides an in-depth exploration of the Context package&amp;rsquo;s semantics, highlighting best practices and common pitfalls to help developers effectively leverage this powerful tool.&lt;/p&gt;</description></item><item><title>JSON - The Fine Print: Part 2 - Emitting JSON</title><link>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-2.html</link><pubDate>Tue, 04 Feb 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-2.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In &lt;a href="https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-1.html"&gt;part 1&lt;/a&gt; we took a high-level view on serialization and JSON. In this part, we&amp;rsquo;ll roll our sleeves and start working with JSON, focused on emitting JSON. You might think this is a basic topic, but there is much more to it than just calling &lt;code&gt;json.Marshal&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="jsonmarshal-vs-jsonencoder"&gt;&lt;code&gt;json.Marshal&lt;/code&gt; vs &lt;code&gt;json.Encoder&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;encoding/json&lt;/code&gt; package has two main APIs: &lt;code&gt;Marshal&lt;/code&gt; and &lt;code&gt;NewEncoder&lt;/code&gt;. The &lt;code&gt;Marshal&lt;/code&gt; function returns a &lt;code&gt;[]byte&lt;/code&gt; while the &lt;code&gt;NewEncoder&lt;/code&gt; function will write to an &lt;code&gt;io.Writer&lt;/code&gt;. The question is: When should you use one API over the other?&lt;/p&gt;</description></item><item><title>Rust, C and C++ Interoperability</title><link>https://www.ardanlabs.com/events/20250219_rust_nation_workshop/</link><pubDate>Mon, 13 Jan 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250219_rust_nation_workshop/</guid><description/></item><item><title>Corporate Training - Ultimate Go: Software Design with K8s</title><link>https://www.ardanlabs.com/events/20250414_zenimax_training/</link><pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250414_zenimax_training/</guid><description/></item><item><title>Corporate Training - Ultimate Software Design and Engineering</title><link>https://www.ardanlabs.com/events/20250512_corporate_training_ugsd/</link><pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20250512_corporate_training_ugsd/</guid><description/></item><item><title>Optimizing Databases on Kubernetes: Kubernetes Backup and Recovery with CNPG and ZFS Snapshots</title><link>https://www.ardanlabs.com/blog/2025/01/optimizing-databases-on-kubernetes-ep5-kubernetes-backup-and-recovery-with-cnpg-and-zfs-snapshots.html</link><pubDate>Mon, 30 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2025/01/optimizing-databases-on-kubernetes-ep5-kubernetes-backup-and-recovery-with-cnpg-and-zfs-snapshots.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In the final episode of the Optimizing Databases on Kubernetes series, Jérôme Petazzoni dives into advanced backup and recovery techniques for PostgreSQL, showcasing how CNPG (Cloud Native PostgreSQL) and ZFS snapshots ensure durability and fast recovery in production environments. This episode focuses on safeguarding data with comprehensive backup strategies, point-in-time recovery, and rapid database cloning, while leveraging ZFS’s efficiency for optimized storage performance.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Comprehensive Backup Strategies:&lt;/strong&gt; Exploring backups with CNPG, including write-ahead logs (WAL) and volume snapshots.&lt;/p&gt;</description></item><item><title>Optimizing Databases on Kubernetes Ep.4: Kubernetes Storage: Benchmarking ZFS, Cloud Disks, and Local Paths</title><link>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep4-kubernetes-storage-benchmarking-zfs-cloud-disks-and-local-paths.html</link><pubDate>Mon, 23 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep4-kubernetes-storage-benchmarking-zfs-cloud-disks-and-local-paths.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In Episode 4 of the Optimizing Databases on Kubernetes series, Jérôme Petazzoni benchmarks the performance of various Kubernetes storage classes, including cloud block storage, ZFS, and Rancher’s Local Path provisioner. This episode dives into the practical aspects of measuring transactions per second, storage efficiency, and durability, offering insights into selecting the right storage solution for database workloads. Through detailed performance comparisons, Jérôme highlights how features like ZFS compression can optimize resource usage and boost database throughput.&lt;/p&gt;</description></item><item><title>Optimizing Databases on Kubernetes Ep.3: Exploring Kubernetes Storage with OpenEBS and ZFS</title><link>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep3-exploring-kubernetes-storage-with-openebs-and-zfs.html</link><pubDate>Wed, 18 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep3-exploring-kubernetes-storage-with-openebs-and-zfs.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In Episode 3 of the Optimizing Databases on Kubernetes series, Jérôme Petazzoni introduces ZFS, a versatile file system renowned for its features like compression, deduplication, and snapshots. Leveraging ZFS with Kubernetes, Jérôme demonstrates how to create efficient and flexible storage solutions, complete with automated setup and configuration using tools like OpenEBS LocalPV. This episode showcases the potential of ZFS to optimize storage performance and reliability in containerized environments.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Overview of ZFS:&lt;/strong&gt; Exploring the features of this advanced file system, from snapshots to RAID configurations.&lt;/p&gt;</description></item><item><title>Optimizing Databases on Kubernetes Ep.2: Automating Database Maintenance with Kubernetes and CNPG</title><link>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep2-automating-database-maintenance-with-Kubernetes-and-cnpg.html</link><pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep2-automating-database-maintenance-with-Kubernetes-and-cnpg.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this episode, Jérôme Petazzoni explores how Kubernetes and CNPG (Cloud Native PostgreSQL) work seamlessly to manage database operations during node maintenance. With real-world demonstrations, Jérôme highlights the power of Kubernetes&amp;rsquo; automation features, such as failover mechanisms and pod disruption budgets, ensuring minimal downtime and maximum reliability for database applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automated Failover with CNPG:&lt;/strong&gt; How Kubernetes handles database switchover during node drains.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pod Disruption Budgets (PDBs):&lt;/strong&gt; Ensuring critical pods remain unaffected during maintenance.&lt;/p&gt;</description></item><item><title>Optimizing Databases on Kubernetes Ep.1: Provisioning a Cluster and Configuring PostgreSQL on Kubernetes</title><link>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep1-provisioning-a-cluster-and-configuring-postgresql-on-kubernetes.html</link><pubDate>Mon, 09 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/12/optimizing-databases-on-kubernetes-ep1-provisioning-a-cluster-and-configuring-postgresql-on-kubernetes.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this introductory episode, Jérôme Petazzoni walks through the critical steps of provisioning a Kubernetes cluster tailored for running databases like PostgreSQL. Leveraging his extensive experience, Jérôme demonstrates practical tools and techniques to establish a scalable, cost-efficient database infrastructure while laying the groundwork for future optimizations covered in this series.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provisioning Kubernetes Clusters:&lt;/strong&gt; A step-by-step guide to creating a reliable cluster using Linode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting Up PostgreSQL with CNPG:&lt;/strong&gt; Deploying production-ready PostgreSQL clusters with built-in replication and backups.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.7: Lock-Free Structures and Channels for Scalable Rust Code</title><link>https://www.ardanlabs.com/blog/2024/12/fearless-concurrency-ep7-lock-free-structures-and-channels-for-scalable-rust-code.html</link><pubDate>Thu, 05 Dec 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/12/fearless-concurrency-ep7-lock-free-structures-and-channels-for-scalable-rust-code.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 7 of the Fearless Concurrency in Rust series! In this final episode, we explore advanced concurrency techniques that enable efficient, scalable, and robust multithreaded applications in Rust. The focus is on leveraging tools like lock-free data structures, channels for thread communication, and strategies for safely managing shared resources in complex systems. These approaches ensure developers can push the limits of Rust’s concurrency model while maintaining safety and performance.&lt;/p&gt;</description></item><item><title>Scalable JSON Streaming with HTTP and Go - Ep.5</title><link>https://www.ardanlabs.com/blog/2024/11/scalable-json-streaming-with--http-and-go.html</link><pubDate>Mon, 25 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/11/scalable-json-streaming-with--http-and-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to the final episode of the JSON for Engineers series! In this concluding session, we tackle the challenges of working with large JSON datasets, exploring efficient strategies for streaming data while minimizing memory usage. These techniques enable developers to handle massive payloads without overburdening system resources, ensuring scalable and cost-effective applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JSON Streaming:&lt;/strong&gt; Using JSON Lines for memory-efficient data transmission.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP Chunked Encoding:&lt;/strong&gt; Leveraging HTTP/1.1 chunked transfer encoding for streaming large datasets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Practical Error Handling:&lt;/strong&gt; Logging and managing errors in streaming JSON responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This episode starts by addressing the inefficiencies of constructing large JSON objects in memory when working with massive datasets, such as database query results. Instead of consuming significant memory to create one monolithic JSON object, the recommended approach involves using JSON Lines (NDJSON), a format where each line represents a separate JSON object. This method reduces memory requirements by transmitting data incrementally. Using Go’s &lt;code&gt;encoding/json&lt;/code&gt; package, developers can easily encode and stream multiple JSON objects, as it automatically appends newlines between objects. On the receiving end, decoding JSON streams requires careful looping to handle incoming data dynamically while avoiding memory reuse issues, which could lead to errors or stale data.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.6: Understanding Rust ARC for Efficient Multithreading</title><link>https://www.ardanlabs.com/blog/2024/11/fearless-concurrency-ep6-understanding-rust-arc-for-efficient-multithreading.html</link><pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/11/fearless-concurrency-ep6-understanding-rust-arc-for-efficient-multithreading.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 6 of the Fearless Concurrency in Rust series! In this episode, we explore the powerful concept of ARC (Atomic Reference Counting) and its critical role in managing shared resources in multithreaded Rust programs. By leveraging ARC, developers can safely share ownership of data across threads without relying on a traditional garbage collector, enabling efficient, flexible, and scalable concurrency.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What is ARC?:&lt;/strong&gt; Understanding Atomic Reference Counting as a lightweight, manual garbage collection system.&lt;/p&gt;</description></item><item><title>JSON Handling and Type Management with Large Datasets in Go - Ep.4</title><link>https://www.ardanlabs.com/blog/2024/10/json-handling-and-type-management-with-large-datasets-in-go.html</link><pubDate>Thu, 14 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-handling-and-type-management-with-large-datasets-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 4 of the JSON for Engineers series! In this episode, we tackle the complexities of working with JSON data, especially when dealing with extensive datasets and optimizing type management. Here, Miki introduces key strategies for managing large JSON documents, avoiding unnecessary type definitions, and using Go’s encoding/json package to handle custom serialization needs effectively.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type Pollution Avoidance:&lt;/strong&gt; Minimizing type declarations by using selective decoding and anonymous structures.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom JSON Serialization:&lt;/strong&gt; Implementing Go’s Marshaler and Unmarshaler interfaces for precise JSON formatting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Working with Mixed-Type Arrays:&lt;/strong&gt; Handling JSON arrays containing diverse types in Go&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Miki begins by addressing the challenge of “type pollution” when working with large JSON responses. When dealing with massive JSON datasets, like data from social trading platforms, defining a separate type for every possible field can quickly lead to an unwieldy codebase. To streamline this, Miki demonstrates how to leverage anonymous structures and selective decoding in Go. By defining only the relevant fields within a function, we can avoid creating additional struct types, making the code more compact and efficient. This technique is especially useful when working with JSON data containing nested fields that may not all be necessary for your application. Through this approach, Go’s encoding/json package will simply ignore any unreferenced fields, allowing you to handle only the data that matters to your project.&lt;/p&gt;</description></item><item><title>Unlock LATAM’s Potential: The Ultimate Outsourcing Product Development Guide</title><link>https://www.ardanlabs.com/news/2024/leveraging-nearshoring-software-development-in-latam-for-success/</link><pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/leveraging-nearshoring-software-development-in-latam-for-success/</guid><description>&lt;p&gt;Let’s face it, you have to be a little crazy to go on your own and start a business; long hours, limited resources, moments full of doubt, a challenge to find key talent and a mine field on a daily basis. While some of these you’re just going to have to face the music, finding talent is one of those things that you can expedite and be cost-effective in the process. Nearshoring in LATAM (Latin America) offers a strategic solution, allowing startups to access skilled talent, reduce costs, and accelerate their time to market. According to a report by Deloitte, 62% of companies believe that nearshoring allows them to focus on core business activities while benefiting from a skilled workforce (Deloitte, 2021).&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.5: Ensuring Memory Safety with Mutexes and RwLocks in Rust</title><link>https://www.ardanlabs.com/blog/2024/11/fearless-concurrency-ep5-ensuring-memory-safety-with-mutexes-and-rwlocks-in-rust.html</link><pubDate>Fri, 08 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/11/fearless-concurrency-ep5-ensuring-memory-safety-with-mutexes-and-rwlocks-in-rust.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 5 of &lt;em&gt;Fearless Concurrency in Rust&lt;/em&gt;! In this episode, Herbert Wolverson dives into advanced concurrency tools, focusing on &lt;code&gt;RwLock&lt;/code&gt; for managing simultaneous reads and writes and the powerful concept of interior mutability. These tools provide developers with greater control over data sharing in multithreaded environments, enabling them to optimize for both performance and code simplicity in Rust.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Read-Write Locks (&lt;code&gt;RwLock&lt;/code&gt;):&lt;/strong&gt; Manage concurrent read and write access efficiently.&lt;/p&gt;</description></item><item><title>2 for 1 Ticket: Workshops with Miki Tebeka</title><link>https://www.ardanlabs.com/events/two-for-one-ticket-workshops-with-miki-tebeka/</link><pubDate>Wed, 06 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/two-for-one-ticket-workshops-with-miki-tebeka/</guid><description>&lt;p&gt;This ticket option will grant you access into both workshops, &amp;ldquo;Getting Started with gRPC&amp;rdquo; &amp;amp; &amp;ldquo;Practical Generics&amp;rdquo;, with instructor Miki Tebeka. The first workshop, &amp;ldquo;Getting Started with gRPC&amp;rdquo;, will be held on December 4th. The second workshop, &amp;ldquo;Practical Generics&amp;rdquo;, will be held on December 11th. Both workshops are 2-hours, in session from 11am-1pm EST.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="getting-started-with-grpc"&gt;Getting Started with gRPC&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, December 4th, 2024 | 11am - 1pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 2-Hour Workshop&lt;/p&gt;</description></item><item><title>Getting Started with gRPC</title><link>https://www.ardanlabs.com/events/getting-startedswith-grpc/</link><pubDate>Wed, 06 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/getting-startedswith-grpc/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, December 4th, 2024 | 11am - 1pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 2-Hour Workshop&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;gRPC is an open source RPC framework from Google. It has become the default choice for internal server to server communication within companies. gRPC is fast, secure, has a schema for incoming and outgoing messages, supports streaming and provides many more benefits.&lt;/p&gt;
&lt;p&gt;In the workshop, we&amp;rsquo;ll write a ride hailing service. We&amp;rsquo;ll build the server, the client and along the way discuss testing, streaming, security and many more subjects. We&amp;rsquo;ll also discuss operational topics such as using TLS, sharing protocol buffers definition and exposing gRPC as REST API.&lt;/p&gt;</description></item><item><title>Practical Generics with Miki Tebeka</title><link>https://www.ardanlabs.com/events/practical-generics-with-miki-tebeka/</link><pubDate>Wed, 06 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/practical-generics-with-miki-tebeka/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, December 11th, 2024 | 11am - 1pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 2-Hour Workshop&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Training&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In this workshop we&amp;rsquo;ll dive into Go&amp;rsquo;s generics (type constraints). We&amp;rsquo;ll discuss why we need generics and when to use them, we&amp;rsquo;ll also see how Go implements generics. We&amp;rsquo;ll go over writing generic functions and generic data types and generic data structures. Finally, we&amp;rsquo;ll see other use cases for generics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before we start, please make sure you have the following:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Ardan Labs Connect4: AI Unveiled with Bill Kennedy</title><link>https://www.ardanlabs.com/events/ardan-labs-connect4-ai-unveiled/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/ardan-labs-connect4-ai-unveiled/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Wednesday, November 13th | 12pm - 1pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Live Stream&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Join our FREE 1-hour live webinar to unveil and explore Ardan Labs’ innovative AI-powered Connect 4 game! Learn about its architecture and how we used Prediction Guard, MongoDB, Google Storage, and GCP to enable real-time learning and strategy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We will cover:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The game&amp;rsquo;s architecture and AI-driven technology&lt;/li&gt;
&lt;li&gt;How MongoDB&amp;rsquo;s Vector database and Google Storage enhance performance&lt;/li&gt;
&lt;li&gt;Insights into cloud-native deployment on Google Cloud Platform (GCP)&lt;/li&gt;
&lt;li&gt;Real-time Q&amp;amp;A session&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;About William Kennedy:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Managing JSON Field Tags and Value Handling in Go - Ep.3</title><link>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-3-managing-json-field-tags-and-value-handling-in-go.html</link><pubDate>Thu, 31 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-3-managing-json-field-tags-and-value-handling-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 3 of JSON for Engineers! In this episode, Miki Tebeka explores the intricacies of JSON field mapping and value handling, especially when working in strongly typed languages like Go. This session covers the practical challenges of matching JSON fields to Go struct fields, distinguishing between missing and zero values, and using default values to ensure robust JSON parsing. These strategies are crucial for engineers managing flexible JSON data structures in a language with strict type requirements.&lt;/p&gt;</description></item><item><title>Transitioning from C and C++ to Rust: A Beginner’s Guide</title><link>https://www.ardanlabs.com/blog/2024/10/transitioning-from-c-and-c++-to-rust.html</link><pubDate>Tue, 29 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/transitioning-from-c-and-c++-to-rust.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;As you embark on the journey from C or C++ to Rust, you&amp;rsquo;ll discover a world of exciting possibilities. Rust&amp;rsquo;s emphasis on safety, concurrency, and performance can significantly enhance your programming toolkit. This beginner&amp;rsquo;s guide on transitioning from C and C++ to Rust will provide a structured approach to making that transition, addressing essential concepts and practical applications. Let’s dive in!&lt;/p&gt;
&lt;h3 id="step-1-understanding-rusts-ownership-model"&gt;Step 1: Understanding Rust’s Ownership Model&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Concept Overview:&lt;/strong&gt;
Rust’s ownership model is its most distinctive feature. Unlike C and C++, where you have pointers and manual memory management, Rust uses a system of ownership with rules that the compiler checks at compile time.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.4: Understanding Mutexes and Thread Safety in Rust</title><link>https://www.ardanlabs.com/blog/2024/10/fearless-concurrency-ep4-understanding-mutexes-and-thread-safety-in-rust.html</link><pubDate>Fri, 25 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/fearless-concurrency-ep4-understanding-mutexes-and-thread-safety-in-rust.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 4 of Fearless Concurrency in Rust! In this episode, we explore how Rust’s ownership and borrowing rules impact multithreaded programming, focusing on the complexities of managing memory in a concurrent environment. We’ll break down how Rust&amp;rsquo;s strict borrowing and ownership model ensures safety and prevents common pitfalls like data races and undefined behavior, making it an ideal choice for building reliable multithreaded applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Thread Safety and Ownership:&lt;/strong&gt; Managing variables across threads using Rust’s ownership rules.&lt;/p&gt;</description></item><item><title>JSON - The Fine Print: Part 1</title><link>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-1.html</link><pubDate>Wed, 23 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-part-1.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Everybody knows &lt;a href="https://www.json.org/"&gt;JSON&lt;/a&gt;, it&amp;rsquo;s a simple serialization format and the default format for REST APIs. Like many other topics, there are fine points you should know in order to work with JSON more effectively and avoid common mistakes.&lt;/p&gt;
&lt;p&gt;In this article we&amp;rsquo;ll explore some big picture aspects and some low level details of using JSON.&lt;/p&gt;
&lt;h3 id="serialization"&gt;Serialization&lt;/h3&gt;
&lt;p&gt;Before diving into JSON, I&amp;rsquo;d like to take a look at serialization in general and discuss common mistakes I&amp;rsquo;ve seen my customers make.&lt;/p&gt;</description></item><item><title>Exploring JSON Encoding and Data Handling in Go - Ep.2</title><link>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-2-exploring-json-encoding-and-data-handling-in-go.html</link><pubDate>Thu, 17 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-2-exploring-json-encoding-and-data-handling-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 2 of JSON for Engineers! In this episode, we explore the unique characteristics of JSON as a schema-less format, discussing both its benefits and challenges. You&amp;rsquo;ll learn how JSON&amp;rsquo;s flexibility, while enabling rapid development, can create issues when working with strongly-typed languages like Go. Additionally, we&amp;rsquo;ll cover the differences between JSON and more compact binary formats, and how to handle JSON’s broader use in web applications.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.3: Managing Threaded Programs and Data Races in Rust</title><link>https://www.ardanlabs.com/blog/2024/10/fearless-concurrency-ep3-optimize-rust-code-with-scoped-threads-&amp;-rayon.html</link><pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/fearless-concurrency-ep3-optimize-rust-code-with-scoped-threads-&amp;-rayon.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 3 of the Fearless Concurrency series! In this episode, Herbert explores advanced threading techniques in Rust, focusing on scoped threads and the Rayon library to help developers build more efficient and parallelized applications. This episode is packed with practical insights on when and how to use different threading models to optimize performance and handle complex workloads.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scoped Threads:&lt;/strong&gt; Ensuring safe access to shared data with guaranteed lifetimes for concurrent threads.&lt;/p&gt;</description></item><item><title>Data Integrity with JSON Serialization - Ep.1</title><link>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-1-data-integrity-with-json-serialization.html</link><pubDate>Thu, 03 Oct 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/10/json-the-fine-print-ep-1-data-integrity-with-json-serialization.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 1 of JSON for Engineers! In this first episode, Miki Tebeka dives into the fundamentals of serialization, with a special focus on JSON, one of the most widely-used data formats in software engineering. Miki draws from his extensive development experience to explain how JSON fits into the bigger picture of data interchange and serialization, laying the groundwork for engineers to use it effectively in real-world applications.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.2: Managing Threaded Programs and Data Races in Rust</title><link>https://www.ardanlabs.com/blog/2024/09/fearless-concurrency-ep2-managing-threaded-programs-and-data-races-in-rust.html</link><pubDate>Thu, 26 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/09/fearless-concurrency-ep2-managing-threaded-programs-and-data-races-in-rust.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 2 of the &lt;em&gt;Fearless Concurrency in Rust&lt;/em&gt; series! In this episode, Herbert Wolverson dives into the fundamentals of threading in Rust, demonstrating how to use Rust’s threading capabilities effectively while maintaining safety. The focus is on using &lt;code&gt;std::thread&lt;/code&gt; to spawn threads, preventing data races, and ensuring efficient, reliable multithreaded execution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Creating Threads in Rust:&lt;/strong&gt; How to spawn and manage operating system threads using &lt;code&gt;std::thread::spawn&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handling Data Races:&lt;/strong&gt; Rust&amp;rsquo;s borrow checker and ownership system preventing unsafe data access across threads.&lt;/p&gt;</description></item><item><title>Ultimate Software Design with Kubernetes</title><link>https://www.ardanlabs.com/events/20241101_ultimate_software_arizona/</link><pubDate>Wed, 25 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20241101_ultimate_software_arizona/</guid><description/></item><item><title>Ep. 7: Enhancing AI with Message Chaining and Accuracy Scoring</title><link>https://www.ardanlabs.com/blog/2024/09/enhancing-ai-with-message-chaining-and-accuracy-scoring-ep7.html</link><pubDate>Thu, 19 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/09/enhancing-ai-with-message-chaining-and-accuracy-scoring-ep7.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to the final episode of our Intro to Generative AI series! In this episode, Daniel Whitenack takes the concepts you&amp;rsquo;ve been learning and shows you how to apply advanced techniques like message chaining and factuality scoring to make your AI-driven systems smarter and more reliable. This session will help you understand how to create workflows that combine multiple models, ensuring your AI can provide accurate, context-aware responses and make decisions grounded in real data.&lt;/p&gt;</description></item><item><title>Fearless Concurrency Ep.1: Rust's Approach to Safe and Manageable Multithreading</title><link>https://www.ardanlabs.com/blog/2024/09/fearless-concurrency-ep1-rusts-approach-to-safe-and-manageable-multithreading.html</link><pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/09/fearless-concurrency-ep1-rusts-approach-to-safe-and-manageable-multithreading.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In Episode 1 of the &lt;em&gt;Fearless Concurrency in Rust&lt;/em&gt; series, Herbert Wolverson introduces the foundational concept of threads in programming, tracing their origins and evolution while demonstrating how Rust handles concurrency in a safer, more manageable way. He explores the history of threads and their role in enabling programs to perform multiple tasks simultaneously, comparing Rust&amp;rsquo;s threading model with traditional approaches in C++ and Go.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Thread Basics and History:&lt;/strong&gt; Understanding how threads function within operating systems and their development over time.&lt;/p&gt;</description></item><item><title>Mid-Level / Senior Backend Engineers with Rust Experience</title><link>https://www.ardanlabs.com/careers/mid-to-senior-level-backend-engineers-with-rust-experience/</link><pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-to-senior-level-backend-engineers-with-rust-experience/</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for Mid-level and Senior Backend Engineers with at least 1 year of Rust experience.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In-depth knowledge of Rust, including idioms, guidelines, and popular libraries (e.g. Serde).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For Senior roles, expertise in Foreign Function Interface development is essential.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience with latency-sensitive systems, algorithms, multi-threaded code, and scalable distributed systems whilst delivering high-quality code from concept to production with a strong focus on security, reliability, performance and observability.&lt;/p&gt;</description></item><item><title>Ep. 6: AI Techniques: Real-Time Web Parsing and Contextual Conversations</title><link>https://www.ardanlabs.com/blog/2024/09/ai-techniques-real-time-web-parsing-and-contextual-conversations-ep6.html</link><pubDate>Thu, 05 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/09/ai-techniques-real-time-web-parsing-and-contextual-conversations-ep6.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In Episode 6 of the Intro to Generative A.I. series, Daniel shifts the focus from basic search techniques to more dynamic, on-the-fly AI applications. He demonstrates how to enhance AI-driven interactions by integrating real-time data retrieval and multi-turn conversations, pushing beyond static data sources to create more responsive and context-aware systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementing real-time parsing and AI search of live websites.&lt;/li&gt;
&lt;li&gt;Enhancing chatbots with the ability to handle and respond to ongoing conversations.&lt;/li&gt;
&lt;li&gt;Creating responsive AI systems that generate answers based on freshly retrieved data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/generative-ai.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>Ep. 5: Key Techniques for Accurate AI-Driven Information Retrieval</title><link>https://www.ardanlabs.com/blog/2024/07/key-techniques-for-accurate-ai-driven-information-retrieval-ep5.html</link><pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/key-techniques-for-accurate-ai-driven-information-retrieval-ep5.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 5 of our Intro to Generative AI series! In this episode, Daniel explores practical techniques for enhancing AI models&amp;rsquo; ability to handle large volumes of text data effectively. He addresses the challenges developers face when working with extensive content, such as entire web pages or internal documents, and provides actionable strategies to optimize the retrieval and processing of relevant information.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Context Handling:&lt;/strong&gt; Splitting large text into manageable chunks while preserving context.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vectorization Techniques:&lt;/strong&gt; Converting text chunks into vector representations for semantic search.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semantic Search:&lt;/strong&gt; Implementing cosine similarity to retrieve relevant information efficiently.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/generative-ai.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>The { Programming } Olympics</title><link>https://www.ardanlabs.com/news/2024/the-programming-olympics/</link><pubDate>Tue, 13 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/the-programming-olympics/</guid><description>&lt;p&gt;&lt;strong&gt;We asked members of our team…&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="what-programming-challenges-should-be-considered-an-olympic-sport"&gt;What programming challenges should be considered an Olympic sport?&lt;/h3&gt;
&lt;p&gt;Imagine if programming had its own Olympic Games—what events would make the cut? We had a blast asking our team this fun question, and their answers were anything but ordinary. From the heart-pounding excitement of Debugging Marathons to the nail-biting drama of Cache Invalidation, the suggestions ranged from the incredibly intense to the downright quirky.&lt;/p&gt;</description></item><item><title>Ep. 4: Streamlining Prompt Engineering and Context Handling in Generative AI</title><link>https://www.ardanlabs.com/blog/2024/07/streamlining-prompt-engineering-and-context-handling-in-generative-ai-ep4.html</link><pubDate>Thu, 08 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/streamlining-prompt-engineering-and-context-handling-in-generative-ai-ep4.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 4 of our Intro to Generative AI series! In this episode, Daniel dives into the essential technique of prompt engineering, focusing on creating dynamic and interactive prompts to enhance the capabilities of AI models.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prompt Templating:&lt;/strong&gt; Techniques for creating and using dynamic prompt templates to enhance AI interactions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Management:&lt;/strong&gt; Strategies for integrating and switching between multiple contexts in AI applications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interactive Systems:&lt;/strong&gt; Building AI systems that respond to user inputs in real-time, using terminal input loops and command-line arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/generative-ai.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>Categorizing Data with Large Language Models in Rust</title><link>https://www.ardanlabs.com/blog/2024/07/categorize_data_large_language_model_rust.html</link><pubDate>Tue, 06 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/categorize_data_large_language_model_rust.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://libreqos.io/"&gt;LibreQoS&lt;/a&gt; is an open source project for monitoring and providing quality-of-experience for Internet Service Providers (ISPs) and large networks. It runs as a &amp;ldquo;middle-box&amp;rdquo;, monitoring traffic that passes through it. It recently gained the ability to track individual &lt;em&gt;data flows&lt;/em&gt; - connections between two endpoints. It&amp;rsquo;s also my favorite Open Source project, to which I contribute regularly.&lt;/p&gt;
&lt;p&gt;Public Internet IP addresses belong to an ASN - an Autonomous System Number. An ASN is a unique number that identifies a network on the Internet. Tracking flows allows you to see which ASNs your users are connecting to, how much data is flowing, and monitor the quality of the connection.&lt;/p&gt;</description></item><item><title>Ep. 12: Implementing Robust Transaction Handling in Go</title><link>https://www.ardanlabs.com/blog/2024/07/implementing-robust-transaction-handling-in-go-ep-12.html</link><pubDate>Mon, 05 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/implementing-robust-transaction-handling-in-go-ep-12.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 12 of our Ultimate Software Design series! In this final installment, Bill guides us through the advanced implementation of transaction management in Go, ensuring robust and consistent data operations within applications. By focusing on middleware integration, Bill provides a comprehensive strategy for handling database transactions, committing successful operations, and rolling back when errors occur.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn to configure and log transaction middleware for tracking commits and rollbacks.’&lt;/p&gt;</description></item><item><title>Optimize Your Databases on Kubernetes With This One Weird Filesystem Trick</title><link>https://www.ardanlabs.com/events/optimize-your-databases-on-kubernetes/</link><pubDate>Mon, 05 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/optimize-your-databases-on-kubernetes/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Thursday, October 17th | 12pm - 1pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What if I told you that you can reduce the size of your databases by 50% and significantly increase their performance, without changing your hardware, without touching your database engine, queries, or indexes, in a completely transparent manner?&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;secret sauce&amp;rdquo; is ZFS and the OpenEBS LocalPV-ZFS CSI driver. There is a lot to unpack here!&lt;/p&gt;</description></item><item><title>Ep. 11: Enhancing Go Code with Effective Application Layer Tests</title><link>https://www.ardanlabs.com/blog/2024/07/proper-prompt-formatting-for-enhanced-ai-model-performance-ep-11.html</link><pubDate>Tue, 30 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/proper-prompt-formatting-for-enhanced-ai-model-performance-ep-11.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 11 of our Ultimate Software Design series! In this episode, Bill delves into the intricacies of implementing robust application layer tests within Go projects, providing developers with essential strategies for creating scalable and maintainable software systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Implement application layer tests that ensure comprehensive coverage with minimal database instances.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Organize tests at the domain level using subtests for easier issue isolation and resilient code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manage dependencies, authentication tokens, and context for smooth information flow and consistent error handling.&lt;/p&gt;</description></item><item><title>Ep. 3: Proper Prompt Formatting for Enhanced AI Model Performance</title><link>https://www.ardanlabs.com/blog/2024/07/ep3-proper-prompt-formatting-for-enhanced-ai-model-performance.html</link><pubDate>Thu, 25 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/ep3-proper-prompt-formatting-for-enhanced-ai-model-performance.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 3 of our Intro to Generative AI series! In this episode, Daniel explores the critical aspect of prompt formatting when working with AI models, emphasizing how proper formatting can significantly enhance the quality of the AI&amp;rsquo;s responses and overall performance.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prompt Formatting:&lt;/strong&gt; Learn the importance of using specific prompt formats for AI models to enhance response quality.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Convenience:&lt;/strong&gt; Discover how chat completions endpoints simplify prompt formatting and improve integration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Response Streaming:&lt;/strong&gt; Understand how to handle real-time, partial completions using server-sent events (SSE) for dynamic AI interactions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/generative-ai.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>Ep. 10: Building Secure Go Systems: Key Management, Middleware, and Error Handling</title><link>https://www.ardanlabs.com/blog/2024/07/building-secure-go-systems-key-management-middleware-and-error-handling-ep-10.html</link><pubDate>Tue, 23 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/building-secure-go-systems-key-management-middleware-and-error-handling-ep-10.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 10 of our Ultimate Software Design series! In this episode, Bill dives into the integration of authentication and authorization mechanisms within Go packages, providing developers with essential strategies for securing and maintaining their software systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn to configure and manage cryptographic keys using a KeyStore and integrate it into your Go applications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover how to create middleware functions for token parsing, user ID extraction, and role-based access control.&lt;/p&gt;</description></item><item><title>Ep. 9: Go Package Design: Authorization and API Structures</title><link>https://www.ardanlabs.com/blog/2024/07/go-package-design-authorization-and-api-structures-ep-9.html</link><pubDate>Wed, 17 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/go-package-design-authorization-and-api-structures-ep-9.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 9 of our Ultimate Software Design series! In this episode, Bill delves into the intricacies of implementing robust authorization and API structure within Go packages, offering invaluable insights for developers aiming to build scalable and maintainable software systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Implement role-based authorization logic for secure and precise access control using Rego scripts.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn best practices for structuring exported and unexported APIs to maintain a clean, intuitive, and maintainable codebase.&lt;/p&gt;</description></item><item><title>Ep. 2: Mastering LLM Integration with Go and Prediction Guard</title><link>https://www.ardanlabs.com/blog/2024/06/ep2-mastering-llm-integration-with-go-and-prediction-guard.html</link><pubDate>Sat, 06 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/ep2-mastering-llm-integration-with-go-and-prediction-guard.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to Episode 2 of our Intro to Generative AI series! In this segment, Daniel dives into the practical aspects of working with large language models (LLMs) using the Go programming language and the Prediction Guard API.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Accessing LLMs:&lt;/strong&gt; Learn how to set up and connect to hosted models using the Go client for Prediction Guard.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt Engineering:&lt;/strong&gt; Discover how to create effective prompts and configure parameters like max tokens and temperature.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output Variability:&lt;/strong&gt; Understand how to manage and utilize variability in AI responses for different results.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/generative-ai.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>Ardan Labs Launches Training Sessions and Expands Services in Latin America</title><link>https://www.ardanlabs.com/news/2024/short-and-advanced-go-training-while-expanding-nearshoring-services-in-latin-america/</link><pubDate>Fri, 05 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/short-and-advanced-go-training-while-expanding-nearshoring-services-in-latin-america/</guid><description>&lt;p&gt;&lt;strong&gt;Chicago, IL at GopherCon U.S 2024 | July 8th, 2024&lt;/strong&gt; &lt;br/&gt;
Ardan Labs, a leading provider of technical training and consulting services, announces the launch of its new &amp;ldquo;Short and Advanced Go Training&amp;rdquo; sessions. These intensive 4-hour live Instructor-led workshops are tailored for experienced Go developers aiming to deepen their expertise and productivity in the Go programming language.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="short-and-advanced-go-training-sessions"&gt;Short and Advanced Go Training Sessions:&lt;/h3&gt;
&lt;p&gt;The specialized training sessions will cover a range of advanced topics crucial for developers looking to enhance their skills efficiently. Key areas of focus include:&lt;/p&gt;</description></item><item><title>Ep. 8: Enhancing Go Application Security with JWT and OPA</title><link>https://www.ardanlabs.com/blog/2024/07/enhancing-go-application-security-with-jwt-and-opa-ep-8.html</link><pubDate>Tue, 02 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/07/enhancing-go-application-security-with-jwt-and-opa-ep-8.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this segment, Bill delves into the fundamental aspects of authentication and authorization, equipping Go developers with essential knowledge and advanced tools to enhance the security of their applications. Through practical examples and detailed explanations, he unpacks the intricacies of these concepts, demonstrating their crucial role in protecting and managing access to your software systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn the distinct roles of verifying user identity and determining access levels.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover how to use JWTs for secure token generation, validation, and expiration management.&lt;/p&gt;</description></item><item><title>GopherCon U.K</title><link>https://www.ardanlabs.com/events/20240825_gophercon_uk/</link><pubDate>Fri, 28 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240825_gophercon_uk/</guid><description/></item><item><title>GopherCon U.K - Workshop</title><link>https://www.ardanlabs.com/events/20240814_gophercon_uk_workshop/</link><pubDate>Fri, 28 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240814_gophercon_uk_workshop/</guid><description/></item><item><title>Fearless Concurrency with Rust</title><link>https://www.ardanlabs.com/events/fearless-concurrency-with-rust/</link><pubDate>Thu, 27 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/fearless-concurrency-with-rust/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Tuesday, August 27 · 11am - 12pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1-Hour Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In this talk, Herbert will discuss Fearless Concurrency – one of Rust’s strongest selling points. What exactly makes concurrency scary to begin with, and how does Rust help? What are the downsides of using a garbage collected model versus a stricter model? The presentation will power through threading models, and how they can help you build fast, safe and correct solutions. We’ll discuss the differences between threading and asynchronous processing – and how each interacts with Rust’s strict, safe memory model. Finally, we’ll put the pedal to the metal – and see just how fast and lean Rust can be.&lt;/p&gt;</description></item><item><title>Ep. 1: Enhancing Your Go Projects with Generative AI: Exploring LLMs</title><link>https://www.ardanlabs.com/blog/2024/06/ep1-enhancing-your-go-projects-with-generative-ai-exploring-llms.html</link><pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/ep1-enhancing-your-go-projects-with-generative-ai-exploring-llms.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Welcome to the first episode of our &amp;ldquo;Intro to Generative A.I&amp;rdquo; series! In this episode, Daniel dives into the intriguing world of large language models (LLMs), providing a comprehensive understanding of how these powerful tools work and their practical applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Gain insights into the architecture and functionality of large language models like Llama 3, and how they process and generate language-based responses.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn how these models can be integrated into Go projects, enhancing capabilities like autocomplete, code generation, and more through practical examples and demonstrations.&lt;/p&gt;</description></item><item><title>Ep. 7: Building Resilient Go Applications: Key Error Handling Techniques</title><link>https://www.ardanlabs.com/blog/2024/06/building-resilient-go-applications-key-error-handling-techniques-ep-7.html</link><pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/building-resilient-go-applications-key-error-handling-techniques-ep-7.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Going into more detail on error handling, Bill provides a comprehensive overview of effective strategies and best practices for Go developers. By exploring the nuances of error management, he equips developers with the tools needed to write more reliable and maintainable code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn the three-step approach to logging errors, determining recovery, and preventing propagation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Understand how treating errors as signals, similar to channels&amp;rsquo; horizontal signaling, enhances error management.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover the importance of implementing trusted errors, shutdown signals, and data validation signals to maintain code integrity and reliability.&lt;/p&gt;</description></item><item><title>Ep. 6: GoRoutines and Error Handling: Essential Techniques for Software Engineers</title><link>https://www.ardanlabs.com/blog/2024/06/goroutines-and-error-handling-essential-techniques-for-software-engineers-ep-6.html</link><pubDate>Fri, 14 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/goroutines-and-error-handling-essential-techniques-for-software-engineers-ep-6.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Continue the dive into the complexities of Go&amp;rsquo;s concurrency model in this segment of the &amp;ldquo;Ultimate Software Design&amp;rdquo; series, where Bill shares essential techniques for managing GoRoutines. Here are three fresh takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Understand the critical role of maintaining proper parent-child relationships in GoRoutine operations to avoid unexpected behaviors and system failures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gain insights into structured techniques for terminating GoRoutines, ensuring that all child processes complete before their parent terminates, to maintain operational integrity.&lt;/p&gt;</description></item><item><title>Ep. 5: Efficient Concurrency in Go: Managing GoRoutines and Load Shedding</title><link>https://www.ardanlabs.com/blog/2024/06/efficient-concurrency-in-go-managing-goroutines-and-load-shedding-ep-5.html</link><pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/efficient-concurrency-in-go-managing-goroutines-and-load-shedding-ep-5.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this installment, Bill delves into the concept of load shedding in Go, explaining its importance in managing GoRoutines and ensuring clean shutdowns.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How to manage GoRoutines using a parent-child relationship model to prevent orphan GoRoutines.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The role of load shedding in maintaining clean and orderly shutdowns, particularly using the HTTP package in Go.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strategies for implementing GoRoutines in Go to handle concurrent tasks efficiently without risking data corruption during shutdowns.&lt;/p&gt;</description></item><item><title>Domain-Driven Data-Oriented Design</title><link>https://www.ardanlabs.com/events/domain-driven-data-oriented-design/</link><pubDate>Mon, 03 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/domain-driven-data-oriented-design/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Thursday, June 27 · 11am - 12pm EST&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1 Hours Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In this talk, Bill will discuss the principles of Domain-Driven Data Oriented Design, emphasizing its significance in software architecture for maintainability and complexity reduction. He will highlight the necessity of package design and layering, stressing the importance of clear architecture to maintain mental models of the codebase. The presentation will cover software architecture layers, data models, and package-oriented design, emphasizing domain-driven design principles and practical implementation strategies. Kennedy will also provide resources for further exploration.&lt;/p&gt;</description></item><item><title>Ep. 4: Mastering Kubernetes Networking: Essential Insights for Efficient Deployment</title><link>https://www.ardanlabs.com/blog/2024/06/mastering-kubernetes-networking-essential-insights-for-efficient-deployment-ep-4.html</link><pubDate>Mon, 03 Jun 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/06/mastering-kubernetes-networking-essential-insights-for-efficient-deployment-ep-4.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this detailed discussion, Bill delves into the critical aspects of networking within Kubernetes clusters, emphasizing the necessity of properly defining services to manage internal and external communication effectively.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn the critical role of service definitions in Kubernetes for managing internal and external communication, ensuring your Go applications are accessible and networked correctly within the cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gain insights into configuring Kubernetes environments to handle traffic routing and service discovery, which is essential for deploying scalable and maintainable Go applications.&lt;/p&gt;</description></item><item><title>Domain-Driven Data Oriented Design</title><link>https://www.ardanlabs.com/events/20240531_domain_driven_data/</link><pubDate>Wed, 29 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240531_domain_driven_data/</guid><description/></item><item><title>Ep. 3: Mastering Kubernetes: Setting Up Environments with Kind</title><link>https://www.ardanlabs.com/blog/2024/05/mastering-kubernetes-setting-up-environments-with-kind-ep-3.html</link><pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/mastering-kubernetes-setting-up-environments-with-kind-ep-3.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this installment of the Ultimate Software Design series, Bill guides us through setting up a Kubernetes environment using Kubernetes inside Docker (kind). He breaks down the structure of Kubernetes and offers insights into effective cluster management, ensuring a robust and efficient development environment.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Effective Cluster Management: Learn the basics of setting up and managing a Kubernetes cluster, essential for maintaining scalable and resilient Go applications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pod and Node Configuration: Understand how to configure pods and nodes to optimize compute resources and ensure seamless application deployment.&lt;/p&gt;</description></item><item><title>Go’s Trace Tooling and Concurrency</title><link>https://www.ardanlabs.com/events/gos-trace-tooling-and-concurrency/</link><pubDate>Tue, 28 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/gos-trace-tooling-and-concurrency/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Tuesday, June 25 · 11am - 12pm EDT&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 1 Hours Free Webinar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Join us for an insightful talk with Bill, where he will demonstrate the use of Go’s trace tooling to analyze a Go program&amp;rsquo;s performance. During the session, Bill will live-code a Go program, incrementally adding concurrency to observe performance variations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key topics include:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Utilizing Go’s trace tooling.&lt;/li&gt;
&lt;li&gt;Understanding Goroutines and concurrency semantics.&lt;/li&gt;
&lt;li&gt;Exploring performance metrics and optimization techniques.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t miss this opportunity to enhance your Go programming skills and deepen your understanding of concurrency and performance analysis.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;About William Kennedy:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>3-Day Rust Training</title><link>https://www.ardanlabs.com/events/20240604_rust_3_day/</link><pubDate>Thu, 23 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240604_rust_3_day/</guid><description/></item><item><title>3-Day Rust Training</title><link>https://www.ardanlabs.com/events/20241202_rust_4_day/</link><pubDate>Thu, 23 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20241202_rust_4_day/</guid><description/></item><item><title>The Guide to Rust Training: Essential Features and Effective Methods</title><link>https://www.ardanlabs.com/news/2024/rust-training-essential-features-and-effective-methods/</link><pubDate>Wed, 22 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/rust-training-essential-features-and-effective-methods/</guid><description>&lt;p&gt;Are you considering enrolling in a Rust training program but are unsure what to look for? Here at Ardan Labs, we have solidified what makes a good and effective training program for our students of all levels. We would like to share our industry insights with you so that you can use them to your advantage. We&amp;rsquo;ll show you the essential features every Rust training should offer, along with effective methods for mastering this programming language.&lt;/p&gt;</description></item><item><title>Ep. 2: Elevating Software Design in Go: Package Architecture in Modern Development</title><link>https://www.ardanlabs.com/blog/2024/05/elevating-software-design-in-go-package-architecture-in-modern-development-ep-2.html</link><pubDate>Tue, 21 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/elevating-software-design-in-go-package-architecture-in-modern-development-ep-2.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;In this insightful episode, Bill dives deep into the realm of package design, shedding light on its crucial role in software development. Here are three key takeaways for Go developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Code Modularity: Learn how Go&amp;rsquo;s packaging system creates essential firewalls between program components, enhancing maintainability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Focused Functionality: Discover the importance of designing packages that provide specific functionality, fostering code clarity.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoiding Pitfalls: Bill warns against common package design mistakes like centralized &amp;ldquo;common&amp;rdquo; packages, promoting a layered approach to maintainable code.&lt;/p&gt;</description></item><item><title>Ep. 6: Exploring Concurrency Pitfalls: Rust vs. C++ and Go</title><link>https://www.ardanlabs.com/blog/2024/05/exploring-concurrency-pitfalls-rust-vs-c-and-go-ep-6.html</link><pubDate>Mon, 20 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/exploring-concurrency-pitfalls-rust-vs-c-and-go-ep-6.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Join Herbert in an insightful discussion on concurrency, where he tackles the complexities of data races and how various programming languages address them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Understand the crucial role of recognizing data races in concurrent programming and their potential impacts.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;See practical examples illustrating the chaos caused by data races and learn how Rust&amp;rsquo;s compiler prevents such issues, ensuring program stability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explore Rust&amp;rsquo;s unique features like null pointer avoidance and reliable error handling, which enhance safety and reliability in concurrent programming tasks.&lt;/p&gt;</description></item><item><title>Ep. 1: Mastering Software Design: Architectural Layers and Coding Modes</title><link>https://www.ardanlabs.com/blog/2024/05/mastering-software-design-architectural-layers-and-coding-modes-ep-1.html</link><pubDate>Tue, 14 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/mastering-software-design-architectural-layers-and-coding-modes-ep-1.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Embark on a journey into the heart of software design with the Ultimate Software Design series, where Bill navigates through the intricacies of crafting robust and maintainable code in Go.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Understand the importance of prioritizing clarity over brevity in code, fostering better understanding and collaboration among Go developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn how to ensure precision in every aspect of Go development, emphasizing the necessity for precise semantic meanings in components, functions, and variables.&lt;/p&gt;</description></item><item><title>Ep. 5: Rust Safe at any Speed: Clearly Indicating Intent</title><link>https://www.ardanlabs.com/blog/2024/05/rust-safe-at-any-speed-clearly-indicating-intent-ep-5.html</link><pubDate>Mon, 13 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/rust-safe-at-any-speed-clearly-indicating-intent-ep-5.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Delving into the intricate realm of type coercion, Herbert&amp;rsquo;s insights offer invaluable guidance for Rust developers grappling with the complexities of data type conversions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn the art of clearly indicating intent in code, a crucial skill for enhancing readability and maintainability in Rust projects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explore Rust&amp;rsquo;s meticulous approach to data mutability, leveraging features like &lt;code&gt;&amp;amp;mut&lt;/code&gt; references to uphold program integrity and prevent unintended modifications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover how embracing Rust&amp;rsquo;s principles of clarity and safety empowers developers to craft robust and reliable codebases, ensuring long-term success in software development endeavors.&lt;/p&gt;</description></item><item><title>Introduction to Generative AI with Go</title><link>https://www.ardanlabs.com/introduction-to-generative-ai-with-go/</link><pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/introduction-to-generative-ai-with-go/</guid><description>&lt;p&gt;Engineers are scrambling to figure out what they can (or should) do with this latest wave of generative AI technologies, and organizations are struggling to bring the technology into enterprise environments. Leaving this webinar, you will be equipped with the practical, hands-on expertise to start integrating generative AI in your Go applications.&lt;/p&gt;
&lt;p&gt;Participants will learn the essential AI engineering skills of prompting, data augmentation, chaining, etc., and they will get hands-on with the latest generative AI models (Mistral, Llama 3, deepseek, etc.).&lt;/p&gt;</description></item><item><title>Rust at Google, Outperforming C++ and Matching Go</title><link>https://www.ardanlabs.com/news/2024/rust-at-google/</link><pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/rust-at-google/</guid><description>&lt;p&gt;At Rust Nation UK, Lars Bergstrom – director of engineering at Google – announced the results of Google’s foray into using Rust. Rust was a great success – and the study’s key points underline Rust’s remarkable efficiency in real-world projects.&lt;/p&gt;
&lt;p&gt;Google tasked different teams with rewriting identical services. The Go and Rust teams finished at the same speed – and the C++ team required twice as long to complete the assigned task. This represents considerable progress for Rust: Rust manages to equal the incredibly productive Go language in development speed.&lt;/p&gt;</description></item><item><title>Ultimate Software Design with Encore</title><link>https://www.ardanlabs.com/events/ultimate-software-design-with-encore/</link><pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/ultimate-software-design-with-encore/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; June 10th - 14th, 2024&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 5 Days/ 5 Hours, from 11am to 4pm EST (GTM - 5)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We have a special offer running for this training: &lt;strong&gt;GET 2 TICKETS for the PRICE OF 1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ticket Prices:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 FOR 1 - Pay $600 and Get 2 Seats: $300 Each&lt;/li&gt;
&lt;li&gt;Individual Ticket Holder - $595&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If you want a 2x1 ticket but don&amp;rsquo;t have someone, send us an email, and we will pair you for the reduced price.&lt;/p&gt;</description></item><item><title>Ep. 4: Type Coercion in Rust: Ensuring Safety and Preventing Data Loss</title><link>https://www.ardanlabs.com/blog/2024/05/type-coercion-in-rust-ep-4.html</link><pubDate>Fri, 03 May 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/05/type-coercion-in-rust-ep-4.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Delving into the intricate realm of type coercion, Herbert&amp;rsquo;s insights offer invaluable guidance for Rust developers grappling with the complexities of data type conversions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Gain insights into the nuances of type coercion, a fundamental aspect of programming languages, and its potential pitfalls, drawing parallels with numerical computation surprises.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explore how Go and Rust tackle inadvertent type coercion, prioritizing program integrity by making it challenging to assign values between incompatible types.&lt;/p&gt;</description></item><item><title>Ep. 3: Ensuring Data Integrity in Rust: Battling Overflow and Underflow</title><link>https://www.ardanlabs.com/blog/2024/29/ensuring-data-integrity-in-rust-ep-3.html</link><pubDate>Mon, 29 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/29/ensuring-data-integrity-in-rust-ep-3.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Delving into the critical issues of overflow and underflow, Herbert&amp;rsquo;s insights offer valuable takeaways for Rust developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rust&amp;rsquo;s static analysis capabilities enable early detection and prevention of overflow and underflow errors, allowing developers to address potential issues before they manifest in runtime environments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Through Rust&amp;rsquo;s emphasis on safety and correctness, developers can leverage built-in mechanisms to handle overflow and underflow situations gracefully, reducing the likelihood of software crashes and unexpected behavior.&lt;/p&gt;</description></item><item><title>Learning Rust: A Guide for Effective Rust Training.</title><link>https://www.ardanlabs.com/news/2024/a-guide-for-effective-rust-training/</link><pubDate>Fri, 26 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/a-guide-for-effective-rust-training/</guid><description>&lt;h3 id="effective-training-methods"&gt;Effective Training Methods&lt;/h3&gt;
&lt;p&gt;Are you eager to explore Rust programming but unsure where to begin? Explore practical applications and effective training methods for your journey of learning Rust.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Rust, renowned for its safety, performance, and concurrency features&lt;/b&gt;, is increasingly becoming the language of choice for a wide range of applications. From system-level programming to web development and beyond, Rust offers unparalleled advantages that make it a valuable asset for developers seeking efficiency and reliability in their code.&lt;/p&gt;</description></item><item><title>Ep. 2: Mastering Memory Safety: Rust's Defense Against Use After Free &amp; Use After Move</title><link>https://www.ardanlabs.com/blog/2024/22/mastering-memory-safety-ep-2.html</link><pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/22/mastering-memory-safety-ep-2.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Exploring the critical issues of &amp;ldquo;use after free&amp;rdquo; and &amp;ldquo;use after move,&amp;rdquo; Herbert’s insights offer a valuable understanding to Rust developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rust&amp;rsquo;s ownership system acts as a powerful safeguard against memory safety issues like &amp;ldquo;use after free&amp;rdquo; and &amp;ldquo;use after move,&amp;rdquo; ensuring code correctness at compile time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;By understanding the risks associated with these memory management pitfalls, Rust developers gain deeper insights into crafting more secure and reliable software, leveraging Rust&amp;rsquo;s robust memory handling mechanisms.&lt;/p&gt;</description></item><item><title>Learning Rust: Why it’s becoming the next trending language</title><link>https://www.ardanlabs.com/news/2024/why-you-should-learn-rust/</link><pubDate>Tue, 16 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/why-you-should-learn-rust/</guid><description>&lt;h3 id="rusts-standout-features"&gt;Rust&amp;rsquo;s Standout Features&lt;/h3&gt;
&lt;p&gt;Are you considering learning a new programming language but unsure where to start? Look no further than Rust.&lt;/p&gt;
&lt;p&gt;In this article, we&amp;rsquo;ll delve into the compelling reasons why Rust is worth your investment of time and effort. From its robust safety features to its exceptional performance advantages, Rust stands out as a language that empowers developers to write reliable and efficient code.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Rust&amp;rsquo;s Safety Features&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First and foremost, &lt;b&gt;Rust prioritizes safety&lt;/b&gt;. Unlike other languages where memory-related bugs can lead to catastrophic failures, Rust&amp;rsquo;s ownership system ensures memory safety without the need for a garbage collector. This feature alone makes Rust a game-changer in building secure and reliable software, reducing the risk of common bugs that plague other languages.&lt;/p&gt;</description></item><item><title>Ep. 1: Defending Against Memory Breaches: Exploring Rust and Go's Safety Mechanisms</title><link>https://www.ardanlabs.com/blog/2024/15/defending-against-memory-breaches-exploring-rust-and-go-safety-mechanisms-ep-1.html</link><pubDate>Mon, 15 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/15/defending-against-memory-breaches-exploring-rust-and-go-safety-mechanisms-ep-1.html</guid><description>&lt;h3 id="introduction"&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;Rust&amp;rsquo;s memory safety features are advantageous to Rust developers because they:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ensure robust protection against buffer overflows and underflows, enhancing the reliability and security of software.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Empower developers to manage type coercion effectively, promoting code reliability and safety while facilitating safe type conversions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Provide confidence in writing concurrent code by enforcing strict mutability rules and synchronization, thereby preventing data race issues and ensuring code correctness and efficiency.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../../images/blog/rust-safe-at-any-speed.jpg?v=1" alt=""&gt;&lt;/p&gt;
&lt;p&gt;With these memory safety features deeply integrated into Rust&amp;rsquo;s design, developers can build more reliable, secure, and efficient software, spanning various aspects of memory management, type handling, and concurrent programming paradigms.&lt;/p&gt;</description></item><item><title>Recruiting Tech Talent from Europe: A Strong Ally in Software Engineering</title><link>https://www.ardanlabs.com/news/2024/-recruiting-tech-talent-from-europe/</link><pubDate>Wed, 03 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/-recruiting-tech-talent-from-europe/</guid><description>&lt;p&gt;In our series of articles on recruitment, we have talked about engineers in Latin America such as Brazil, Mexico and Argentina, we also talked about the skills of engineers who come from the USA and Canada. Now it&amp;rsquo;s Europe&amp;rsquo;s turn.&lt;/p&gt;
&lt;p&gt;The software engineering landscape is global, but Europe has emerged as a powerhouse brimming with talent and innovation. Here, we explore the rich resources Europe offers and why recruiting from this region can be highly beneficial.&lt;/p&gt;</description></item><item><title>95% Faster Cold Start times - For any AI/ML/Large Container</title><link>https://www.ardanlabs.com/reducing-container-cold-start-time/</link><pubDate>Tue, 26 Mar 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/reducing-container-cold-start-time/</guid><description>&lt;p&gt;Managing software distribution at scale is a significant challenge for enterprises. Specifically, applications cannot commence until they are deployed and installed on a node. Additionally, when deploying large numbers of applications to thousands of machines locally, globally, or into HPC compute clusters, network load issues arise. For example, deploying a 1GB application to 1000 nodes requires transmitting 1TB over your network! Considering that AI/ML applications typically are larger than 4GB and can easily exceed 10GB this can be a considerable improvement.&lt;/p&gt;</description></item><item><title>For Loops and More in Go</title><link>https://www.ardanlabs.com/blog/2024/03/for-loops-and-more-in-go.html</link><pubDate>Tue, 12 Mar 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/03/for-loops-and-more-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Looping seems like a basic topic: Write a &lt;code&gt;for&lt;/code&gt; loop with a termination condition, and you&amp;rsquo;re done. However there&amp;rsquo;s a lot of ways you can write a &lt;code&gt;for&lt;/code&gt; loop in Go. Knowing more about the different versions of &lt;code&gt;for&lt;/code&gt; will help you choose the best option to accomplish your tasks and it will help you prevent some bugs.&lt;/p&gt;
&lt;h3 id="some-assembly-required"&gt;Some Assembly Required&lt;/h3&gt;
&lt;p&gt;What kind of code is generated by the compiler for a &lt;code&gt;for&lt;/code&gt; loop? To keep things simple, I will produce the assembly for an empty loop:&lt;/p&gt;</description></item><item><title>Advantages of Hiring Top-Tier Engineering Talent in the US and Canada</title><link>https://www.ardanlabs.com/news/2024/hiring-top-tier-engineering-talent-in-the-US-and-canada/</link><pubDate>Thu, 07 Mar 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/hiring-top-tier-engineering-talent-in-the-US-and-canada/</guid><description>&lt;p&gt;For numerous organizations, acquiring engineering talent can present significant challenges, particularly when relying on conventional sourcing methods. Scouring job websites or relying on recruiters who may not fully understand your technology stack or specific requirements can be time-consuming and often leads to suboptimal results. And even if you do come across a highly skilled engineer, their rates might be beyond your budget.&lt;/p&gt;
&lt;p&gt;So, what sets Ardan Labs apart in addressing these challenges? Over the past 12 years, we&amp;rsquo;ve diligently cultivated a global network of talented engineers who trust us and are eager to collaborate with Ardan Labs. This extensive network allows us to offer you a diverse pool of engineers with varying levels of experience, while ensuring that they align with your budgetary constraints without compromising on quality.&lt;/p&gt;</description></item><item><title>PDB, Evictions, Priority Classes: Kubernetes During Rush Hour</title><link>https://www.ardanlabs.com/kubernetes-durring-rush-hour/</link><pubDate>Tue, 27 Feb 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/kubernetes-durring-rush-hour/</guid><description>&lt;div class="alert alert-info"&gt;
Gophers, &lt;b&gt;you filled the event in just 24hrs!&lt;/b&gt; Upon many requests, we have extended our number of tickets to make more available just for you. Mark your calendars &amp; sign up while there are &lt;b&gt;still seats available!&lt;/b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;p&gt;Learn how to keep your Kubernetes clusters healthy and your applications happy when their resource usage increases to critical levels.&lt;/p&gt;
&lt;p&gt;Discover the difference between &lt;strong&gt;&amp;ldquo;Eviction&amp;rdquo;&lt;/strong&gt; and &lt;strong&gt;&amp;ldquo;Preemption&amp;rdquo;&lt;/strong&gt;, and how to leverage advanced concepts like &lt;strong&gt;&amp;ldquo;Pod Disruption Budgets&amp;rdquo;&lt;/strong&gt;. Glean tidbits of information along the way (like the meaning of that &lt;strong&gt;&amp;ldquo;NOMINATED NODE&amp;rdquo;&lt;/strong&gt; column in &lt;strong&gt;&amp;ldquo;kubectl get pods -o wide&amp;rdquo;&lt;/strong&gt;).&lt;/p&gt;</description></item><item><title>Latin America Rising: Enhance Your Engineering Teams</title><link>https://www.ardanlabs.com/news/2024/latin-america-rising-enhance-your-engineering-teams/</link><pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/latin-america-rising-enhance-your-engineering-teams/</guid><description>&lt;p&gt;You need engineering resources and you’re back to the same old ways you’ve always used to find someone. Maybe you’re using a job website or working with the same old recruiter who has never understood your tech stack or real needs. In any case, you’re spending time you don’t have and our guess is you’re not finding the actual talent you need. If you do find a solid engineer, you can’t afford them.&lt;/p&gt;</description></item><item><title>Rust: Safe at any Speed</title><link>https://www.ardanlabs.com/events/20240221_rust_safe_at_any_speed/</link><pubDate>Wed, 14 Feb 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240221_rust_safe_at_any_speed/</guid><description/></item><item><title>GopherCon Europe 2024 Winter Edition with Ardan Labs</title><link>https://www.ardanlabs.com/news/2024/gc-eu-2024-winter-edition-with-ardan-labs/</link><pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/gc-eu-2024-winter-edition-with-ardan-labs/</guid><description>&lt;h3 id="about-gophercon-europe"&gt;About GopherCon Europe&lt;/h3&gt;
&lt;p&gt;As Go&amp;rsquo;s popularity soared, GopherCon went global and GopherCon Europe (GCEU) kicked off its inaugural conference in 2018 in Reykjavik, Iceland. After that, GCEU had plans to rotate the conference every year in different countries and in 2019 the conference was held in Tenerife, Spain. However, due to the impact of COVID-19 it became important to transition the conference to an online format.&lt;/p&gt;
&lt;p&gt;From that point on, Berlin has served as the primary base for the conference hosting both the online and in-person events. The Ardan Labs team and our very own Bill Kennedy have been supporters of GCEU since their first year. Today, GCEU has become an institution across the globe — a platform covering the entire Go spectrum for knowledge sharing, community building, and inspiration.&lt;/p&gt;</description></item><item><title>Recruitment: The Role of Qualified Engineers</title><link>https://www.ardanlabs.com/news/2024/recruitment-the-role-of-qualified-engineers/</link><pubDate>Wed, 24 Jan 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/recruitment-the-role-of-qualified-engineers/</guid><description>&lt;h3 id="the-role-of-qualified-engineers-in-shaping-future-of-modern-enterprises"&gt;The Role of Qualified Engineers in Shaping Future of Modern Enterprises&lt;/h3&gt;
&lt;p&gt;The engineers - the superheroes with a knack for problem-solving, creative thinking, and adaptability fuel businesses to stay ahead in the fast-paced tech landscape.&lt;/p&gt;
&lt;p&gt;Investing in top-tier engineering talent isn&amp;rsquo;t just a strategy; it&amp;rsquo;s the secret sauce to superior product quality, heightened efficiency, and a distinct edge in the market.&lt;/p&gt;
&lt;p&gt;Let’s explore some real-time success stories of onboarding quality engineers and finding spectacular improvements in products and services.&lt;/p&gt;</description></item><item><title>Staff Augmentation: Power Up Your Team for Business Success</title><link>https://www.ardanlabs.com/news/2024/staff-augmentation-power-up-your-team-for-business-success/</link><pubDate>Thu, 18 Jan 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/staff-augmentation-power-up-your-team-for-business-success/</guid><description>&lt;p&gt;In the fast-paced world of corporate dynamism, every company seeks the perfect moves to amp up efficiency, slash costs, and emerge as the undisputed champion. Enter the secret weapon: Staff Augmentation.&lt;/p&gt;
&lt;h3 id="whats-the-buzz-about-staff-augmentation"&gt;What&amp;rsquo;s the Buzz About Staff Augmentation?&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s the art of roping in short-term warriors, the freelance superheroes, to swoop in and save the day. Think of it as assembling your Avengers team but for your workforce.&lt;/p&gt;
&lt;h3 id="whos-riding-the-staff-augmentation-wave"&gt;Who&amp;rsquo;s Riding the Staff Augmentation Wave?&lt;/h3&gt;
&lt;p&gt;Everyone! From the agile startups to the colossal titans like Google, Apple, Amazon, Microsoft, and IBM. They&amp;rsquo;ve all got their Avengers assembled.&lt;/p&gt;</description></item><item><title>Ultimate Go Tour</title><link>https://www.ardanlabs.com/blog/2024/01/ultimate-go-tour.html</link><pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2024/01/ultimate-go-tour.html</guid><description>&lt;p&gt;I have always appreciated the Go Team investing time on providing the community with the &lt;a href="https://go.dev/tour"&gt;Go Tour&lt;/a&gt;. This website is designed to help developers get started in learning the Go programming language. The nice part of the website is that it provides an interactive environment where one can read, write, and run Go examples.&lt;/p&gt;
&lt;p&gt;Since the first time I’ve navigated this tour, I’ve had a few problems. First, this tour is not comprehensive both in the number of examples and the content explaining the examples. Second, the content goes from beginner to expert almost instantly. I’ve always wanted to extend and improve the tour, but since this is a Google property, no one except Google employees can work on it.&lt;/p&gt;</description></item><item><title>A Case Study on Exploring Nearshoring Potential: A Roadmap for Global Dominance</title><link>https://www.ardanlabs.com/news/2024/a-case-study-on-exploring-nearshoring-potential/</link><pubDate>Wed, 10 Jan 2024 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2024/a-case-study-on-exploring-nearshoring-potential/</guid><description>&lt;p&gt;Nearshoring success? How do we make it happen? For many companies, choosing between nearshoring and offshoring becomes tricky. Nevertheless, there are numerous success stories associated with nearshoring.&lt;/p&gt;
&lt;p&gt;This case study explores the successes of a few industry leaders like HubSpot, Whirlpool, Duolingo, and Shopify embracing nearshoring as a transformative strategy.&lt;/p&gt;
&lt;h3 id="nearshoring-vs-offshoring"&gt;Nearshoring vs. offshoring&lt;/h3&gt;
&lt;p&gt;While we talk about nearshoring, let&amp;rsquo;s explore offshoring a little as well. Offshoring entails outsourcing to a distant location, frequently in a different continent, whereas nearshoring involves outsourcing to a geographically closer location, often within the same region or continent. The decision between nearshoring and offshoring hinges on factors like cost considerations, necessary expertise, cultural compatibility, and logistical preferences.&lt;/p&gt;</description></item><item><title>GopherCon Europe: Winter In Athens</title><link>https://www.ardanlabs.com/events/gophercon-europe-winter-in-athens/</link><pubDate>Wed, 06 Dec 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/gophercon-europe-winter-in-athens/</guid><description>&lt;h4 id="in-partnership-with-ardan-labs"&gt;In Partnership with Ardan Labs&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; Feb 6th - 8th, 2024&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Amalia Hotel - Athens, Greece&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="ticket-options"&gt;Ticket Options&lt;/h4&gt;
&lt;a class="ticket-image" href="http://events.ardanlabs.com/products/gophercon-eu-in-partnership-with-ardan-labs-early-bird-ticket-conference-workshops" target="_blank"&gt;
&lt;img src="../../images/events/gceu-athens/early-ticket-soldout.jpg" /&gt;
&lt;/a&gt;
&lt;a class="ticket-image" href="https://events.ardanlabs.com/products/early-gopher-self-paid-only-conference-pass" target="_blank"&gt;
&lt;img src="../../images/events/gceu-athens/conf-only-euro.jpg" /&gt;
&lt;/a&gt;
&lt;a class="ticket-image" href="https://events.ardanlabs.com/products/self-paid-gopherconeu-winter-in-athens-conference-workshop" target="_blank"&gt;
&lt;img src="../../images/events/gceu-athens/late-ticket-euro.png" /&gt;
&lt;/a&gt;
&lt;a class="ticket-image" href="http://events.ardanlabs.com/products/corporate-gophercon-europe-winter-edition-in-collaboration-with-ardan-labs-conference-workshop" target="_blank"&gt;
&lt;img src="../../images/events/gceu-athens/corp-ticket-euro.jpg" /&gt;
&lt;/a&gt;
&lt;p&gt;Our &lt;strong&gt;Self-Paid Conference Only Ticket&lt;/strong&gt; is an in-person conference admission which does &lt;strong&gt;NOT&lt;/strong&gt; include entry to workshops.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Late Gopher Ticket &amp;amp; Corporate Ticket&lt;/strong&gt; is an in-person full conference admission, including a full-day workshop.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="workshops"&gt;Workshops:&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;February 7th 2024 at 9:00am.&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ultimate Go: Software Design with Kubernetes with Bill Kennedy&lt;/li&gt;
&lt;li&gt;Ultimate Go with Miki Tebeka&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;img class="workshop-instructor" src="../../images/events/gceu-athens/bill-workshop.png" /&gt;
&lt;h4 id="full-day-workshop-ultimate-go-software-design-with-kubernetes"&gt;&lt;strong&gt;Full-Day Workshop:&lt;/strong&gt; Ultimate Go: Software Design with Kubernetes&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Instructor:&lt;/strong&gt; Bill Kennedy&lt;/p&gt;</description></item><item><title>Ultimate Go with Miki Tebeka</title><link>https://www.ardanlabs.com/events/ultimate-go-with-miki-tebeka/</link><pubDate>Tue, 05 Dec 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/ultimate-go-with-miki-tebeka/</guid><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; February 19th - 22nd, 2024&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; 4 Days/ 4 Hours, from 8am to 12pm EST (GTM - 5)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; Online - Zoom Meeting&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The workshop is composed of four 4-hour sessions. It is aimed toward developers who have experience with Go and would like to understand how to write more efficient code and understand data semantics and concurrency patterns. We’ll cover many coding best practices that help write precise code.&lt;/p&gt;</description></item><item><title>Rust Nation: UK</title><link>https://www.ardanlabs.com/events/20240326_rust_nation_uk/</link><pubDate>Sun, 03 Dec 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/events/20240326_rust_nation_uk/</guid><description/></item><item><title>Visualizing Map Data with Go and Leaflet JS</title><link>https://www.ardanlabs.com/blog/2023/11/visualizing-map-data-go.html</link><pubDate>Thu, 23 Nov 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/11/visualizing-map-data-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;This year I set a personal goal of walking for a total of 1,000 kilometers and I’m proud to say I’m close to hitting that goal. I’ve been tracking all the different routes I take in an app named &lt;a href="https://www.strava.com/dashboard"&gt;Strava&lt;/a&gt;. One nice feature of Strava is that the app provides access to the raw data in a format called &lt;a href="https://en.wikipedia.org/wiki/GPS_Exchange_Format"&gt;GPX&lt;/a&gt;. Starva can visualize the route in their app, but I wanted to try and perform my own visualization. That brought me to this blog post about using &lt;a href="https://leafletjs.com"&gt;Leaflet JS&lt;/a&gt; to plot one of my walks on a map.&lt;/p&gt;</description></item><item><title>Fintech Consulting Success Story</title><link>https://www.ardanlabs.com/news/2023/10/fintech-consulting-success-story/</link><pubDate>Thu, 26 Oct 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2023/10/fintech-consulting-success-story/</guid><description>&lt;h3 id="go-powered-transformation-ardan-labs-fintech-consulting-success-story"&gt;Go-Powered Transformation: Ardan Labs Fintech Consulting Success Story&lt;/h3&gt;
&lt;p&gt;In today&amp;rsquo;s fast-paced and highly competitive financial services industry, streamlined software development can be a game-changer for companies aiming to stay ahead of the curve. With the rise of digital financial solutions, fintech companies and traditional financial institutions are increasingly relying on robust services to facilitate real-time secure transactions with seamless customer experiences.&lt;/p&gt;
&lt;p&gt;One programming language that has been gaining significant traction in finance is Go. In this post, we will explore how Go is transforming software development for financial companies while making the process more efficient, secure, and scalable.&lt;/p&gt;</description></item><item><title>Implementing Enumerations In Go</title><link>https://www.ardanlabs.com/blog/2023/09/implementing-enumerations-in-golang.html</link><pubDate>Thu, 21 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/09/implementing-enumerations-in-golang.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Prior to coding in Go, I was writing software in C#. In C# enumerations can be declared and the associated type can be used in functions and as fields in a struct. The compiler won’t allow a value of the enumerated type to be passed or set that doesn’t belong to the defined set. This is something that I have missed since coding in Go.&lt;/p&gt;
&lt;p&gt;Go doesn’t have enumerations and it can be a problem at times when you want type safety for a well-defined set of values. A common way people try to have enumerations in Go really doesn’t work for me because of the way &lt;a href="https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html"&gt;constants&lt;/a&gt; behave. That being said, I have developed a pattern that gets me as close as possible to what I had in C# though it’s not perfect and I will explain.&lt;/p&gt;</description></item><item><title>Slices Package: Contains, Delete, and Equal</title><link>https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html</link><pubDate>Fri, 08 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html</guid><description>&lt;h3 id="series"&gt;Series&lt;/h3&gt;
&lt;p&gt;Here are all the posts in this series about the slices package.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html"&gt;Binary Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html"&gt;Clip, Clone, and Compact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html"&gt;Compare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html"&gt;Contains, Delete, and Equal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the last post of this series, I discussed the &lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html"&gt;Compare&lt;/a&gt; API from the slices package. In this post, I will share how the &lt;code&gt;Contains&lt;/code&gt;, &lt;code&gt;Delete&lt;/code&gt;, and &lt;code&gt;Equal&lt;/code&gt; APIs work.&lt;/p&gt;
&lt;h3 id="contains"&gt;Contains&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;Contains&lt;/code&gt; API reports whether a specified value exists in a specified collection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Listing 1&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Slices Package: Compare</title><link>https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html</link><pubDate>Fri, 25 Aug 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html</guid><description>&lt;h3 id="series"&gt;Series&lt;/h3&gt;
&lt;p&gt;Here are all the posts in this series about the slices package.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html"&gt;Binary Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html"&gt;Clip, Clone, and Compact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html"&gt;Compare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html"&gt;Contains, Delete, and Equal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the last post of this series I discussed the &lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html"&gt;Clip, Clone, and Compact&lt;/a&gt; APIs from the slices package. In this post, I will share how the &lt;code&gt;Compare&lt;/code&gt; and &lt;code&gt;CompareFunc&lt;/code&gt; APIs work.&lt;/p&gt;
&lt;h3 id="compare"&gt;Compare&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;Compare&lt;/code&gt; API can be used to compare two slices and determine if the slices are equal or which one is shorter. Shorter meaning the slice with the lesser of the two values at the same index position. Less can be obvious like with integers, or needs to be custom defined like with structs.&lt;/p&gt;</description></item><item><title>Slices Package: Clip, Clone, and Compact</title><link>https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html</link><pubDate>Fri, 18 Aug 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html</guid><description>&lt;h3 id="series"&gt;Series&lt;/h3&gt;
&lt;p&gt;Here are all the posts in this series about the slices package.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html"&gt;Binary Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html"&gt;Clip, Clone, and Compact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html"&gt;Compare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html"&gt;Contains, Delete, and Equal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the &lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html"&gt;first post&lt;/a&gt; of this series, I discussed the binary search API from the slices package that is now part of the standard library with the release of version 1.21. In this post, I will share how the &lt;code&gt;Clip&lt;/code&gt;, &lt;code&gt;Clone&lt;/code&gt;, and &lt;code&gt;Compact&lt;/code&gt; APIs work.&lt;/p&gt;
&lt;h3 id="clip"&gt;Clip&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;Clip&lt;/code&gt; API can be used to remove unused capacity from a slice. This means reducing the capacity of the slice to match its length.&lt;/p&gt;</description></item><item><title>Slices Package: Binary Search</title><link>https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html</link><pubDate>Wed, 02 Aug 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html</guid><description>&lt;h3 id="series"&gt;Series&lt;/h3&gt;
&lt;p&gt;Here are all the posts in this series about the slices package.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-binary-search.html"&gt;Binary Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-clip-clone-compact.html"&gt;Clip, Clone, and Compact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/08/golang-slices-compare.html"&gt;Compare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2023/09/golang-slices-contains-delete-equal.html"&gt;Contains, Delete, and Equal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Go’s most important data structure is the slice and it was designed from the beginning to be mechanically sympathetic with the hardware. To learn more about that, check out Bill Kennedy’s &lt;a href="https://www.ardanlabs.com/training/individual-on-demand/ultimate-go-bundle/"&gt;Ultimate Go&lt;/a&gt; video. Thanks to the introduction of generics in Go 1.18, the language team has been experimenting with a new package called slices. This package provides an API that provides various functions that are useful when working with slices.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Extensible API Handlers Ep. 10</title><link>https://www.ardanlabs.com/blog/2023/04/interfaces-101-extensible-api-handlers-ep-10.html</link><pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/04/interfaces-101-extensible-api-handlers-ep-10.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 9, Miki discussed how a command flag can be decoded into a user defined type with the &lt;code&gt;Value&lt;/code&gt; interface. As a recap, the &lt;code&gt;Value&lt;/code&gt; interface consists of two methods: one for serializing the underlying concrete type and one for deserializing a string into an object. To put this interface to the test, Miki wrote a command that had a flag to specify a network address. While implementing the &lt;code&gt;Set&lt;/code&gt; method of the &lt;code&gt;Value&lt;/code&gt; interface, Miki demonstrated how to add validation for your program’s flags.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Parsing Command Flags Ep. 9</title><link>https://www.ardanlabs.com/blog/2023/03/interfaces-101-parsing-command-flags-ep-9.html</link><pubDate>Mon, 27 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/interfaces-101-parsing-command-flags-ep-9.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 8, Miki developed a Go HTTP client that had a method to check the health of a theoretical API. The method would construct the request URL and return an error based on the response code received from the server. Miki then created a type that would mock Go’s &lt;code&gt;http.RoundTripper&lt;/code&gt; interface and replace his client’s transport with said type to test it. To improve the efficacy, Miki’s stub will simulate an erroneous response to see if his client’s &lt;code&gt;Health&lt;/code&gt; method is working as intended.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Testing with a Mock Interface Ep. 8</title><link>https://www.ardanlabs.com/blog/2023/03/interfaces-101-testing-with-a-mock-interface-ep-8.html</link><pubDate>Mon, 20 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/interfaces-101-testing-with-a-mock-interface-ep-8.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 7, Miki discussed design considerations to keep in mind while creating interfaces in Go with the first idea he proposed being that an interface should represent what we need from a type, and not what is stored on the type. To add some clarity to this thought, Miki explained how the &lt;code&gt;io.Reader&lt;/code&gt; and &lt;code&gt;io.Writer&lt;/code&gt; interfaces each require one method to be implemented although the underlying concrete type may store more information. The second idea he proposed was that interfaces should be small, with less than 6 methods, to ensure your code remains composable.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Interface Design Considerations Ep. 7</title><link>https://www.ardanlabs.com/blog/2023/03/interfaces-101-interface-design-considerations.html</link><pubDate>Mon, 13 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/interfaces-101-interface-design-considerations.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 6, Miki built a logger package with the aim of making it as versatile as possible. To achieve this, he constructed his logger object with a function that would: accept the &lt;code&gt;io.Writer&lt;/code&gt; interface as a parameter and perform type assertions to retrieve other interface types as needed. By building this, Miki demonstrated how polymorphism is achieved with Go by changing the type of a variable with type assertions.&lt;/p&gt;</description></item><item><title>Calculating Download MD5 Hash</title><link>https://www.ardanlabs.com/blog/2023/03/calculating-download-md5-in-go.html</link><pubDate>Thu, 09 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/calculating-download-md5-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;One of the exercises I give to students is to download a single big file over HTTP concurrently using several goroutines using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests"&gt;HTTP Range&lt;/a&gt; requests. An extra part of the exercise is to validate the downloaded file from a known MD5 signature. This extra part turns out to be interesting, let&amp;rsquo;s have a look.&lt;/p&gt;
&lt;h3 id="getting-download-information"&gt;Getting Download Information&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s make an HTTP HEAD request to get information about a file located in a public dataset stored on Google Cloud Storage (GCS).&lt;/p&gt;</description></item><item><title>Rust Programming Language: Simple Game</title><link>https://www.ardanlabs.com/blog/2023/03/rust-programming-language-simple-game.html</link><pubDate>Wed, 08 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/rust-programming-language-simple-game.html</guid><description>&lt;p&gt;&lt;strong&gt;with Cheikh Seck&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;This is the first in a series of posts that will explore the Rust programming language. I am going to take the same approach I did with Go and write little programs that explore the different features of the language. Before I begin that work, I thought it would be fun to write a program that does something fun.&lt;/p&gt;
&lt;p&gt;In this post and my first ever Rust program, I’m going to use a Rust library called &lt;a href="https://github.com/amethyst/bracket-lib"&gt;bracket-lib&lt;/a&gt; that provides a cross-platform terminal emulator. I will use this library to build a simple game window that will allow me to animate a box that can be moved up, with gravity causing it to move back down.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Interface Type Assertion Ep. 6</title><link>https://www.ardanlabs.com/blog/2023/03/interfaces-101-interface-type-assertions.html</link><pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/03/interfaces-101-interface-type-assertions.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 5, Miki wrote a function that counted the number of lines in a file with interfaces. The first thing his function did was to open a file with Go’s &lt;code&gt;os.Open&lt;/code&gt; function. Miki chose this method because the variable returned by said function implements the &lt;code&gt;io.Reader&lt;/code&gt; interface which is crucial for the next step. The remaining parts of this function consisted of a primitive type alias that satisfied the &lt;code&gt;io.Writer&lt;/code&gt; interface and tracked the number of lines by increasing the &lt;code&gt;Write&lt;/code&gt; method’s receiver value. To put the process in motion, Miki will invoke function &lt;code&gt;io.Copy&lt;/code&gt; to trigger his type alias’ &lt;code&gt;Write&lt;/code&gt; method and in essence, count the number of lines in the file.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Determine LOC with io.Writer Ep. 5</title><link>https://www.ardanlabs.com/blog/2023/02/interfaces-101-determine-loc-with-iowriter.html</link><pubDate>Mon, 27 Feb 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/02/interfaces-101-determine-loc-with-iowriter.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 4, Miki defined an enumerated type that satisfied Go’s &lt;code&gt;fmt.Stringer&lt;/code&gt; interface. By implementing the &lt;code&gt;fmt.Stringer&lt;/code&gt; interface, Miki can specify how his enumerators were printed within a formatted string and in this case, he expected the values to be displayed as a predetermined text value. Miki also pointed out how using the value of the method’s receiver within the &lt;code&gt;Stringer&lt;/code&gt; method can result in a recursive loop.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../../images/blog/interfaces-05.jpg?v=1" alt=""&gt;&lt;/p&gt;</description></item><item><title>Interfaces 101 : Go's Logging Interface Ep. 4</title><link>https://www.ardanlabs.com/blog/2023/02/interfaces-101-go-logging-interface.html</link><pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/02/interfaces-101-go-logging-interface.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 3, Miki implemented a type that satisfied Go’s &lt;code&gt;error&lt;/code&gt; interface. The odd thing about his type was it would be considered not-nil although no value was set for it. To get a better understanding of the situation, Miki gives a brief explanation of how Go determines if an error value is nil, and in this case, Miki specified the type of the variable returned to be a pointer of his custom error type which blindsided Go’s mechanism to determine a nil value. Miki chose this example because it demonstrated the importance of declaring an error with its type set as the &lt;code&gt;error&lt;/code&gt; interface.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Error Handling With Go Ep. 3</title><link>https://www.ardanlabs.com/blog/2023/02/interfaces-101-error-handling-with-go.html</link><pubDate>Mon, 13 Feb 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/02/interfaces-101-error-handling-with-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 2, Miki examined the impact interfaces have on the performance of a Go program. To perform this experiment, Miki invoked a type’s method in two ways: with the concrete type and as an interface function to measure the difference in execution time. The conclusion of this experiment was that calling a method with the concrete type is faster than using an interface. During the experiment, Miki made use of the build flag &lt;code&gt;-gcflag=’-m’&lt;/code&gt; to display which variables were being allocated on the heap and where the compiler was automatically &lt;code&gt;inlining&lt;/code&gt; function calls.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Heap Escape Ep. 2</title><link>https://www.ardanlabs.com/blog/2023/02/interfaces-101-heap-escape.html</link><pubDate>Wed, 08 Feb 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/02/interfaces-101-heap-escape.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 1, Miki had two functions that performed the similar operation, but returned different types. To refactor this, Miki rewrote both functions as a generic function that allowed him to specify the type to be returned during invocation. In some cases, the compiler may not recognise a type, thus, Miki gives a few pointers on manually telling a generic function which type to use. After demonstrating how to return different types with a generic function, Miki limited the types his generic function would accept with an interface.&lt;/p&gt;</description></item><item><title>Interfaces 101 : Implementing Generics with Interfaces Ep. 1</title><link>https://www.ardanlabs.com/blog/2023/01/interfaces-101-implementing-generics-with-interfaces.html</link><pubDate>Tue, 31 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/interfaces-101-implementing-generics-with-interfaces.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Go interfaces are beneficial to Go developers because they:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow interfaces to separate mechanism from behavior.&lt;/li&gt;
&lt;li&gt;Increase flexibility of function parameters.&lt;/li&gt;
&lt;li&gt;Enable mocking of function parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the addition of generics in Go 1.18, interfaces can be used to constrain the types of values a generic function will accept. To dive deeper into Go interfaces, we invite you to join Miki in his latest series dedicated to Go interfaces.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 20</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-20.html</link><pubDate>Fri, 27 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-20.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 19, Bill designed and implemented the data structure for an account on his blockchain. This type will have a nonce field to ensure incoming transactions are valid and performed in order. Since the database will be stored in memory and not on disk, the balances in these accounts are reconstructed with information from previous transactions and the genesis block.&lt;/p&gt;
&lt;p&gt;In this video, Bill takes all the theories discussed in this series and applies them by launching his first blockchain node. Bill starts by defining a database type that will house all the account information on his blockchain with the initial values populated by the genesis record. Once he is finished, Bill will add a new package named &lt;code&gt;state&lt;/code&gt; and, as the name implies, it will manage the state on his blockchain. Watch and learn how to launch a blockchain node and interface with it over HTTP.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 18</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-18.html</link><pubDate>Tue, 24 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-18.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 17, Bill began to design an in-memory accounting database that will store the account balances on his blockchain. To build this database, Bill will add a memory pool on each node that stores a list of public addresses with their respective balances. The balances on these addresses are reconstructed by reading the previous transaction records found on his blockchain.&lt;/p&gt;
&lt;p&gt;In this video, Bill will define the types of transactions his blockchain will support. The first step Bill takes is to define the &lt;code&gt;transaction&lt;/code&gt; data type and give a full walkthrough of the reasoning behind the fields he chose for this data type. Next, he’ll define methods for this type that will validate a transaction. While writing this code, Bill will borrow a few concepts from Ethereum to build a reference implementation. Watch to learn how transactions are managed on the blockchain and how to define one on your blockchain.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 19</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-19.html</link><pubDate>Tue, 24 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-19.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 18, Bill defined the Go type that will represent a transaction and implemented the methods to validate one. While developing the transaction type, Bill states that he’ll be borrowing concepts from Ethereum to ensure that he’s building a reference implementation. Bill’s transaction type has a field named &lt;code&gt;nonce&lt;/code&gt;, similar to Ethereum, that ensures transactions are executed in order. The nonce value of the last transaction is stored in his accounting database and later compared for additional verification.&lt;/p&gt;</description></item><item><title>Table driven tests in Go</title><link>https://www.ardanlabs.com/blog/2023/01/table-driven-tests-in-go.html</link><pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/table-driven-tests-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Table tests are a great way to test different inputs and associated outputs for a function in Go. To write a table test, you define a slice of some data struct with fields of the input data you’ll need and the expected outcome. Then you can loop through this slice and pass the data stored for each element to your function. One disadvantage of table tests is as the data set in your slice grows, the harder it is to find the failing case. Luckily, Miki will share some tips to manage this with the Go test suite.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 17</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-17.html</link><pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-17.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 16, Bill implemented additional means of verification for his blockchain’s transactions. The first update he made was to verify if a transaction is destined for his blockchain by reading the first byte of the signature. The next one Bill made was to recalculate the public address from a signature and compare it with the &lt;code&gt;from&lt;/code&gt; field of the transaction to verify if the request is valid. While building this, Bill demonstrates how a user’s private key transforms into their public address.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 16</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-16.html</link><pubDate>Tue, 17 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-16.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 15, Bill architected a solution to ensure all the users on his blockchain were given a unique identifier. His approach consisted of essentially leveraging the randomness of a user&amp;rsquo;s private key to ensure each identifier is unique. A disadvantage Bill pointed out with this is that a user may forget their private key and ultimately lose access to their account. To circumvent this issue, Bill proposed the usage of a mnemonic, that is composed of 12 to 24 words, to act as the private key since it’s simpler to keep track of and hard to guess.&lt;/p&gt;</description></item><item><title>Writing an HTTP handler function in Go</title><link>https://www.ardanlabs.com/blog/2023/01/writing-an-http-handler-function-in-go.html</link><pubDate>Tue, 17 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/writing-an-http-handler-function-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;When an API requires implementation details from the user, many developers use an interface for help. However, another way to allow developers to provide implementation details for an API is to accept a function instead. Go supports declaring function types which can be used to define a contract similar to how interfaces define a contract. A good example of an API that uses functions over an interface is the HTTP package. The HTTP package has the user bind a handler function into different routes.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 15</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-15.html</link><pubDate>Thu, 12 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-15.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 14, Bill architected a solution to digitally sign the transactions on his blockchain. His solution retrieved the private key by : loading private key data from disk, parsing the key data and returning the ECDSA private key. The private key is then used to generate the signature of a transaction. While writing the code to perform this functionality, Bill highlighted how a blockchain node can use a transaction’s signature to extrapolate the public key.&lt;/p&gt;</description></item><item><title>Writing testable examples in Go</title><link>https://www.ardanlabs.com/blog/2023/01/writing-testable-examples-in-go.html</link><pubDate>Thu, 12 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/writing-testable-examples-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Google developed Go to be an alternative to C++ with the internet and scale in mind. Go’s toolchain automates tasks that are easily overlooked, and amongst those tasks is generating documentation. Go has the ability to generate documentation based on comments written in your source code. As the end user, you have the choice to view this documentation in your terminal or, if your code is publicly accessible, on &lt;a href="https://pkg.go.dev"&gt;pkg.go.dev&lt;/a&gt;. Go also offers special comment syntax to further format and style the generated documentation.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 13</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-13.html</link><pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-13.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 12, Bill laid out his strategy to handle data hashing on his blockchain. The first step he took was to create a package to handle the cryptographical aspects of his blockchain. After that, he wrote a hash function that met the requirements outlined in his strategy. This function took transaction data as a parameter and returned a hexadecimal representation of the hash. To implement this function, Bill imported packages from the Go standard library and Ethereum API.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 14</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-14.html</link><pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-14.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 13, Bill discussed the idea of adding salt to a hash and how modern crypto-currency blockchains use it to better interpret requests sent to nodes. He continued by defining a function called &lt;code&gt;stamp&lt;/code&gt; that embeds a salt within a hash. While writing the function, Bill stated that he would use keccak256 as it’s the same algorithm used by Ethereum to generate hash values. Bill will use the APIs provided with Go Ethereum to generate a keccak256 hash. He plans on reusing the stamp function in the future to digitally sign transactions performed on his blockchain.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 12</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-12.html</link><pubDate>Wed, 04 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-12.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 11, Bill highlighted the issue of identity verification and provided a solution to this problem. The solution proposed was to cryptographically sign a transaction to verify its authenticity. Bill chose to implement a solution making use of the Elliptic Curve Digital Signature Algorithm (ECDSA) as the public key can be extracted from a signature. Although a small distinction, the ability to re-compute a public key is essential in a decentralized and distributed environment.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 10</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-10.html</link><pubDate>Tue, 03 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-10.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 9, Bill introduced the idea of the genesis record and its role in his blockchain. As a recap, the genesis record will be used to customize the settings of his blockchain. The approach Bill takes here is similar to how Ethereum operates because he is storing the record in JSON format.&lt;/p&gt;
&lt;p&gt;In this video, Bill starts by defining the Go types his blockchain will use. The first type he defines will represent the genesis record. This type will be populated by the data found in the genesis record and will ensure Bill reaps all the benefits of using strongly typed language. Before he proceeds with the next type definition, he highlights the possible limitations he can encounter by using type &lt;code&gt;uint64&lt;/code&gt;. Watch to learn how to write idiomatic and durable Go code that will load your blockchain’s settings from disk.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 11</title><link>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-11.html</link><pubDate>Tue, 03 Jan 2023 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2023/01/ultimate-go-advanced-engineering-episode-11.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 10, Bill dove into the technical implementation of his genesis record and defined a custom Go type representing the record. While doing so, he provided an in-depth look at the reasoning behind the fields he included.. After declaring this type, Bill wrote a function that loads the genesis record from disk and onto memory. His function will use the standard library &lt;code&gt;encoding/json&lt;/code&gt; package to load JSON data from a hard-coded file path.&lt;/p&gt;</description></item><item><title>Smart Contracts Using Solidity and Go: Basic Contract</title><link>https://www.ardanlabs.com/blog/2022/12/smart-contract-solidity-go-basic.html</link><pubDate>Wed, 21 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/smart-contract-solidity-go-basic.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I made it my mission in 2022 to learn everything I could about blockchain and as the year ends, I feel like I accomplished my goal. Love it, hate it, or don’t want to know nothing about it, I think it’s important to push your opinions aside and understand how this technology works. Even with the current &lt;a href="https://en.wikipedia.org/wiki/Bankruptcy_of_FTX"&gt;collapse&lt;/a&gt; of several large crypto companies in 2022, blockchain isn’t going to disappear. Bitcoin and Ethereum are here to stay. If anything, this past year has shown how entrenched blockchain has become in the world and in people’s lives.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 9</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-9.html</link><pubDate>Tue, 20 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-9.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 8, Bill wanted to build a blockchain in Go and began to lay the groundwork for the project. Go is a good choice because its standard library has the necessary network and cryptographical functionality required to build a blockchain. Unlike the previous segment, Bill plans to use this blockchain to manage accounts and balances with hypothetical assets. Bill will reuse concepts from ethereum, bitcoin and the previous segment of the series to implement this blockchain.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 7</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-7.html</link><pubDate>Mon, 19 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-7.html</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In episode 6, Bill gives an overview of what consensus algorithms are and how these algorithms ensure distributed databases are in sync. Moving forward Bill will adopt the proof of authority (PoA) algorithm as a means to determine which node has the ability to write the next record. To jog your memory, PoA is a consensus mechanism where identity is used as a stake. By implementing this algorithm, Bill will add transparency to his dependency manager as he is no longer the only user with the ability to add new records. The dependency manager now meets the teams’ requirements for transparency, however, it will have low throughput since only one record can be shared and inserted at a time.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 8</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-8.html</link><pubDate>Mon, 19 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-8.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first part of the series, Bill designed a dependency management system. The dependency manager needed to be distributed, transparent, cryptographically auditable and scalable. To meet these requirements, Bill borrowed concepts from blockchain. He did this to illustrate how the blockchain can be repurposed and used to accomplish the mundane task of dependency management. While doing so, Bill indirectly highlighted the problems a blockchain solves.&lt;/p&gt;
&lt;p&gt;In the next segment of the series, Bill will build a semantically correct blockchain. He plans to perform this task entirely with Go and he’lll re-use the ideas described in the previous segment to further facilitate your understanding of what a blockchain is. Early on Bill admits he is no economist, and for the sake of the series he will use a hypothetical pot of gold as the starting equity for his blockchain. Follow along and learn how assets are “on-ramped” into the blockchain.&lt;/p&gt;</description></item><item><title>Generics vs. Interfaces</title><link>https://www.ardanlabs.com/blog/2022/12/generic-vs-interfaces.html</link><pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/generic-vs-interfaces.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In this video, Paulo shows the benefit of leveraging generic functions to write less code that does more. He starts by walking you through an API server he initially wrote that makes use of Go’s default HTTP handlers with a sprinkle of GORM to manage database transactions. He then refactors that code by introducing the concept of adapter functions.&lt;/p&gt;
&lt;p&gt;Paulo’s approach consists of decoupling his business logic with his API code. To achieve this, he defines an adapter function that will establish a bridge between his business logic and API server handlers. This proves to be an effective way to abstract request processing and handling. This approach also promotes code reusability because the business logic is loosely coupled with the API service invoking it.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 5</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-5.html</link><pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-5.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In case you missed episode 4, Bill attempted to integrate current database sharing solutions to solve the “database ownership” problem his dependency manager faces. He tried providing copies of the database, implementing a load balancer and replication. While performing these experiments, Bill identified the qualities his dependency manager’s database needs to have for users to trust it. He closed episode 4 by stating that his dependency manager needs a database that is distributed, cryptographically auditable, synchronized and scalable. By implementing this Bill hoped to provide greater transparency for his dependency manager.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 6</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-6.html</link><pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-6.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the last video, Bill left off talking about proof of work (PoW) algorithms. In a distributed and decentralized environment, PoW used to be the gold standard for a node to participate equitably in a Blockchain. However, with PoW as the number of nodes on the Blockchain increases, the amount of energy waste increases. This is because each node is performing the same computationally heavy calculation and only one node’s energy usage is leveraged to write the next block.&lt;/p&gt;</description></item><item><title>Understanding Go's Time Format</title><link>https://www.ardanlabs.com/blog/2022/12/understanding-go-time-format.html</link><pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/understanding-go-time-format.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Most apps that work with time values eventually need to display time to a user. Go has a unique way of allowing you to specify how to display time values that is different from the C library function &lt;code&gt;strftime&lt;/code&gt;. The &lt;code&gt;strftime&lt;/code&gt; function tends to be the standard for languages and tooling to format time. Go developed its own format specification instead of using any existing format with the idea of being able to maintain a mental model for formatting time.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 3</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-3.html</link><pubDate>Wed, 14 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-3.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 2, Bill designed a database for his dependency manager to enable Go developers to have reproducible,durable and secure builds. This database will house the hash value for each of the dependencies stored. During runtime, these hash values are compared with the dependencies a user has locally. Bill’s tool makes this comparison to make sure the user has the right version of the dependency. Each team making use of Bill’s dependency manager will have access to its database, however, his database lacked any means to reliably perform audits.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 4</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-4.html</link><pubDate>Wed, 14 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-4.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 3, Bill needed to figure out how to share ownership of his dependency manager’s database in a secure and efficient manner. Bill is the only stakeholder with full access to his dependency manager’s database. That is, he is the only person with the ability to mutate the database. This is problematic because he can freely edit the database which will make it harder for other users to confidently perform audits. And as a result, reduce the perceived transparency of his dependency manager.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 2</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-2.html</link><pubDate>Tue, 13 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-2.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In episode 1, Bill finished by describing the dependency management conundrum Go faced in its early days. Prior to the Go team providing the module system, developers were on their own to find a solution. Engineers in the Go community did propose different solutions, but there was no general consensus on which tool to use for dependency management.&lt;/p&gt;
&lt;p&gt;In this video, Bill will begin to architect a solution to the reproducible build problem. By doing so, you will learn how blockchain hashing works and then Bill will share how centralizing this dependency database will cause other problems. One of these problems is people eventually losing trust in the database because only one stakeholder, Bill, can make changes to it without a means for users to detect the change. He closes this segment with an important question, “how do we establish trust for this CLI’s database?”&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering Episode 1</title><link>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-1.html</link><pubDate>Mon, 12 Dec 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/12/ultimate-go-advanced-engineering-episode-1.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In this video, Bill will introduce the concepts of what a blockchain is, the benefits of a blockchain, and the network environment it operates in. Bill describes a blockchain as a single, append-only, transparent, publicly available and cryptographically auditable database. Blockchains operate using a peer to peer (p2p) network with no single node designated as the central authority.&lt;/p&gt;
&lt;p&gt;To better understand what all that means, Bill begins to work through a familiar problem of creating reproducible, durable, and secure builds that software teams face. It’s a real problem the Go team eventually solved with the new module system. As Bill uncovers different problems that present themselves, he introduces different blockchain concepts that can help provide a solution.&lt;/p&gt;</description></item><item><title>Practical Uses Of Blockchain Technology</title><link>https://www.ardanlabs.com/blog/2022/06/practical-uses-blockchain-technology.html</link><pubDate>Mon, 06 Jun 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/06/practical-uses-blockchain-technology.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;A blockchain is an integrated solution of different computer science problems in the form of a single, &lt;a href="https://en.wikipedia.org/wiki/Append-only"&gt;append-only&lt;/a&gt;, publicly available, &lt;a href="https://tinyurl.com/4psep8et"&gt;transparent&lt;/a&gt;, and cryptographically auditable database that runs in a distributed and decentralized environment.&lt;/p&gt;
&lt;p&gt;I’ve heard many times that blockchain is a technology looking for a problem to solve. I disagree with that assessment because the tech and computer science behind blockchain has practical uses in everyday engineering problems. One use of this technology that comes to mind is a dependency management verification system.&lt;/p&gt;</description></item><item><title>Blockchain In Go: Part IV: Fraud Detection</title><link>https://www.ardanlabs.com/blog/2022/05/blockchain-04-fraud-detection.html</link><pubDate>Thu, 05 May 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/05/blockchain-04-fraud-detection.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first three posts, I explained there were four aspects of a blockchain that this series would explore with a backing implementation provided by the Ardan blockchain project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/02/blockchain-01-digital-accounts-signatures-verification.html"&gt;Digital accounts with electronic signatures and verification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/03/blockchain-02-transaction-distribution-synchronization.html"&gt;Transaction distribution and synchronization between computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/04/blockchain-03-redundant-storage-and-consensus.html"&gt;Redundant storage and consensus by different computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/05/blockchain-04-fraud-detection.html"&gt;Detection of any fraud to past transactions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first post focused on how the Ardan blockchain provides support for digital accounts, signatures, and verification. The second post focused on transaction distribution and synchronization between different computers. The third post, focused on how the Ardan blockchain handles consensus between different computers which results in the redundant storage of the blockchain database. In this fourth post, I will focus on how the Ardan blockchain can detect forgery or changes to the underlying blocks and transaction data.&lt;/p&gt;</description></item><item><title>Blockchain In Go: Part III: Redundant Storage And Consensus</title><link>https://www.ardanlabs.com/blog/2022/04/blockchain-03-redundant-storage-and-consensus.html</link><pubDate>Tue, 19 Apr 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/04/blockchain-03-redundant-storage-and-consensus.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first two posts, I explained there were four aspects of a blockchain that this series would explore with a backing implementation provided by the Ardan blockchain project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/02/blockchain-01-digital-accounts-signatures-verification.html"&gt;Digital accounts with electronic signatures and verification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/03/blockchain-02-transaction-distribution-synchronization.html"&gt;Transaction distribution and synchronization between computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/04/blockchain-03-redundant-storage-and-consensus.html"&gt;Redundant storage and consensus by different computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/05/blockchain-04-fraud-detection.html"&gt;Detection of any fraud to past transactions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first post focused on how the Ardan blockchain provides support for digital accounts, signatures, and verification. The second post focused on transaction distribution and synchronization between different computers. In this third post, I will focus on how the Ardan blockchain handles consensus between different computers which results in the redundant storage of the blockchain database.&lt;/p&gt;</description></item><item><title>Senior Golang Engineer [Australia] | Ardan Labs</title><link>https://www.ardanlabs.com/careers/senior-backend-engineer-apac-australia.html</link><pubDate>Mon, 11 Apr 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/senior-backend-engineer-apac-australia.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for Senior Backend Engineers with at least 2 years of Go experience.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Develop, design and review new features in high-throughput fault-tolerant microservices for an IoT-style real-time monitoring system used by thousands of payment terminals.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Collaborate with your fellow highly-skilled engineers and testers in a fast-paced, constructive nibble environment.&lt;/p&gt;</description></item><item><title>Blockchain In Go: Part II: Transaction Distribution and Synchronization</title><link>https://www.ardanlabs.com/blog/2022/03/blockchain-02-transaction-distribution-synchronization.html</link><pubDate>Tue, 08 Mar 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/03/blockchain-02-transaction-distribution-synchronization.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first post, I explained there were four aspects of a blockchain that this series would explore with a backing implementation provided by the Ardan blockchain project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/02/blockchain-01-digital-accounts-signatures-verification.html"&gt;Digital accounts with electronic signatures and verification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/03/blockchain-02-transaction-distribution-synchronization.html"&gt;Transaction distribution and synchronization between computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/04/blockchain-03-redundant-storage-and-consensus.html"&gt;Redundant storage and consensus by different computers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2022/05/blockchain-04-fraud-detection.html"&gt;Detection of any fraud to past transactions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first post focused on how the Ardan blockchain provides support for digital accounts, signatures, and verification. In this second post, I will focus on transaction distribution and synchronization between different computers (blockchain nodes).&lt;/p&gt;</description></item><item><title>Blockchain In Go: Part I: Digital Accounts, Signatures and Verification</title><link>https://www.ardanlabs.com/blog/2022/02/blockchain-01-digital-accounts-signatures-verification.html</link><pubDate>Sat, 12 Feb 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/02/blockchain-01-digital-accounts-signatures-verification.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;This is the first post in a series that will explore the semantics and implementation details of the Ardan &lt;a href="https://github.com/ardanlabs/blockchain"&gt;blockchain&lt;/a&gt; project. The code is a reference implementation of a blockchain and not intended to mirror any specific blockchain in use today. Even though the code has been engineered with production level coding standards, I wouldn&amp;rsquo;t use this project for anything more than learning.&lt;/p&gt;
&lt;p&gt;I am using the &lt;a href="https://github.com/ethereum/go-ethereum"&gt;Ethereum&lt;/a&gt; project as a reference and have taken inspiration from that code. I’m hoping that understanding the code inside the Ardan blockchain will give you enough knowledge to understand the code that runs Ethereum.&lt;/p&gt;</description></item><item><title>Visualization in Go - Plotting Stock Information</title><link>https://www.ardanlabs.com/blog/2022/01/visualizations-in-go.html</link><pubDate>Mon, 17 Jan 2022 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2022/01/visualizations-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;d like to visualize some stock data using Go, but after looking at the Go ecosystem you see very little in charting. You find &lt;a href="https://github.com/gonum/plot"&gt;gonum&lt;/a&gt;, which has some plotting capabilities, but it generates static charts. It&amp;rsquo;s 2022, and you&amp;rsquo;d like to have interactive features such as zooming, panning, and more. You turn to the HTML landscape, and see many more options and decide to take this path. After a short survey, you decide to use &lt;a href="https://plotly.com/javascript/"&gt;plotly&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>GIS in Go</title><link>https://www.ardanlabs.com/blog/2021/11/gis-in-go.html</link><pubDate>Mon, 01 Nov 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2021/11/gis-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;You are jogging and want to show off your route to your friends. Let’s imagine the data you have for your route is a CSV file in the following format:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Listing 1: track.csv&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;time,lat,lng,height
2015-08-20 03:48:07.235,32.519585,35.015021,136.1999969482422
2015-08-20 03:48:24.734,32.519606,35.014954,126.5999984741211
2015-08-20 03:48:25.660,32.519612,35.014871,123.0
2015-08-20 03:48:26.819,32.519654,35.014824,120.5
2015-08-20 03:48:27.828,32.519689,35.014776,118.9000015258789
2015-08-20 03:48:29.720,32.519691,35.014704,119.9000015258789
2015-08-20 03:48:30.669,32.519734,35.014657,120.9000015258789
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Listing 1 shows the first few lines of &lt;code&gt;track.csv&lt;/code&gt;. Each line contains a time stamp in &lt;a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time"&gt;UTC&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Latitude"&gt;latitude&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Longitude"&gt;longitude&lt;/a&gt; and height above sea level in meters.&lt;/p&gt;</description></item><item><title>Mid-level and Senior Backend Engineers with Ruby experience</title><link>https://www.ardanlabs.com/careers/mid-level-senior-ruby-engineer.html</link><pubDate>Thu, 16 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-level-senior-ruby-engineer.html</guid><description>&lt;p&gt;We have an exciting opportunity to join a very dynamic team in a growing and ever-changing industry within a SaaS project. We are looking for independent experienced engineers with at least 5 years of experience who are looking to take their career to the next level.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Understanding of the syntax of Ruby and its nuances&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Understanding of object-oriented analysis and design&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience as a Ruby on Rails developer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience in software development&lt;/p&gt;</description></item><item><title>Blockchain Core Developer</title><link>https://www.ardanlabs.com/careers/blockchain-core-developer.html</link><pubDate>Wed, 15 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/blockchain-core-developer.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for a Blockchain Core Developer with strong experience in systems programming.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strong systems programming skills in Go, Rust, or C++.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At least 2 years of prior work experience in systems programming in Go, Rust or C++ (not necessarily in the blockchain space).&lt;/p&gt;</description></item><item><title>Infrastructure Engineer</title><link>https://www.ardanlabs.com/careers/infrastructure-engineer.html</link><pubDate>Tue, 14 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/infrastructure-engineer.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for an Infrastructure Engineer with experience in various AWS technologies.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3+ years of experience as a Software Engineer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Backend Engineering Experience&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience with one or more AWS Technologies like: ECS (Fargate), Lambda, Glue, RDS Aurora, DynamoDB, ALBs, VPCs, Kinesis, SQS, SNS, CloudFront&lt;/p&gt;</description></item><item><title>Data Engineer</title><link>https://www.ardanlabs.com/careers/data-engineer.html</link><pubDate>Mon, 13 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/data-engineer.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for a Data Engineer with experience in technologies like AWS, Stitch, RedShift, and others.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3+ years of experience as a Software Engineer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strong SQL skills are required&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience with core AWS services&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data processing tools like Stitch, DBT, Spark&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data warehousing tools like Redshift, Snowflake&lt;/p&gt;</description></item><item><title>Extract, Transform, and Load in Go</title><link>https://www.ardanlabs.com/blog/2021/09/extract-transform-load-in-go.html</link><pubDate>Mon, 13 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2021/09/extract-transform-load-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;You are about to visit Boston, and would like to taste some good food. You ask your friend who lives there what are good places to eat. They reply with &amp;ldquo;Everything is good, you can&amp;rsquo;t go wrong&amp;rdquo;. Which makes you think, maybe I should check where &lt;em&gt;not&lt;/em&gt; to eat.&lt;/p&gt;
&lt;p&gt;The data geek in you arises, and you find out that the city of Boson has a &lt;a href="https://data.boston.gov/dataset/food-establishment-inspections"&gt;dataset of food violations&lt;/a&gt;. You download it and decide to have a look.&lt;/p&gt;</description></item><item><title>Mid-level / Senior Full Stack Engineer</title><link>https://www.ardanlabs.com/careers/mid-level-or-senior-full-stack-engineer.html</link><pubDate>Sun, 12 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-level-or-senior-full-stack-engineer.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for a Mid-level / Senior Full Stack Engineer with experience in front-end javascript technologies.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;5+ years of experience writing software professionally.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strong proficiency in modern Typescript / Javascript both in browser and server contexts.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Significant experience building, testing and maintaining internal and public-facing RESTful or GraphQL APIs.&lt;/p&gt;</description></item><item><title>DevOps Engineer</title><link>https://www.ardanlabs.com/careers/devops-engineer.html</link><pubDate>Sat, 11 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/devops-engineer.html</guid><description>&lt;p&gt;Ardan Labs is a high-performance software consulting firm that helps to develop reliable solutions and applications.&lt;/p&gt;
&lt;p&gt;One of our clients needs help in solving interesting and large-scale problems through Devops best practices.&lt;/p&gt;
&lt;h3 id="the-role"&gt;The Role&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Automation (Orchestrate systems provisioning, processes)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keep the lights on (day-to-day administration)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nurture DevOps best practices&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="must-have-skills"&gt;Must-Have Skills&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Proven track record as a DevOps engineer in a fast-paced environment&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experience with AWS infrastructure (VPC, Security Groups, ECS, S3)&lt;/p&gt;</description></item><item><title>Mid-level and Senior Backend Engineers with Go experience</title><link>https://www.ardanlabs.com/careers/mid-level-and-senior-backend-engineer.html</link><pubDate>Fri, 10 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-level-and-senior-backend-engineer.html</guid><description>&lt;p&gt;Ardan Labs is a consulting firm that helps our clients develop software solutions and applications. We work on software projects and teams of different sizes. We are currently looking for Mid-level and Senior Backend Engineers with at least 1 year of Go experience.&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Can demonstrate a good working knowledge of Go, standard library, idioms and common guidelines.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can demonstrate the ability to collaborate with team members, flushing out designs to finalizing solutions.&lt;/p&gt;</description></item><item><title>Mid-level to Senior VUE.JS Engineer</title><link>https://www.ardanlabs.com/careers/mid-level-senior-vue-js-engineer.html</link><pubDate>Thu, 09 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-level-senior-vue-js-engineer.html</guid><description>&lt;p&gt;Hiring 100% Remote (USA, Canada &amp;amp; LATAM only).&lt;/p&gt;
&lt;p&gt;Looking for a Vue.JS (Nuxt, Vueify) engineer with 2+ years of experience to work on a challenging project. The project will require the following additional know how:&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CSS and HTML&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GraphQL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Knowledge of Finance / Payment gateways might be good but not necessary.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="benefits"&gt;Benefits&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;As a W2 employee, we offer family medical coverage, life insurance, paid vacation, and technical training.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Mid-level to Senior React Native Engineer</title><link>https://www.ardanlabs.com/careers/mid-level-senior-react-native-engineer.html</link><pubDate>Wed, 08 Sep 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/careers/mid-level-senior-react-native-engineer.html</guid><description>&lt;p&gt;We have a great opportunity that will be dedicated to mobile app development in a large enterprise. We are looking for engineers with the following experience:&lt;/p&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2-4 years experience with React Native (required)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1-2 years GraphQL or Go (optional)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The opportunity could also include some API development with our existing engineers, so GraphQL or Go experience is optional. If you are ready to take on a new challenge, please apply!&lt;/p&gt;</description></item><item><title>Data Science in Go: How Much To Tip</title><link>https://www.ardanlabs.com/blog/2021/07/go-data-science-how-much-tip.html</link><pubDate>Tue, 27 Jul 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2021/07/go-data-science-how-much-tip.html</guid><description>&lt;h3 id="the-question"&gt;The Question&lt;/h3&gt;
&lt;p&gt;When you work on data science problems, you always start with a question you&amp;rsquo;re trying to answer. This question will affect the data you pick, your exploration process, and how you interpret the results.&lt;/p&gt;
&lt;p&gt;The question for this article is: How much (in percentage) should you tip your taxi driver?&lt;/p&gt;
&lt;p&gt;To answer the question, we&amp;rsquo;ll use a portion of the &lt;a href="https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page"&gt;NYC Taxi dataset&lt;/a&gt;. The data file we&amp;rsquo;ll be using is &lt;a href="https://github.com/353words/taxi/raw/master/taxi-01-2020-sample.csv.bz2"&gt;taxi-01-2020-sample.csv.bz2&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Using Bitmasks In Go</title><link>https://www.ardanlabs.com/blog/2021/04/using-bitmasks-in-go.html</link><pubDate>Fri, 09 Apr 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2021/04/using-bitmasks-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;You write a server for a massively multiplayer online role-playing game (&lt;a href="https://en.wikipedia.org/wiki/Massively_multiplayer_online_role-playing_game"&gt;MMORPG&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;In the game, players collect keys and you want to design how to store the set of keys each player has.&lt;/p&gt;
&lt;p&gt;As an example, imagine the set of keys are &lt;code&gt;copper&lt;/code&gt;, &lt;code&gt;jade&lt;/code&gt; and &lt;code&gt;crystal&lt;/code&gt;. You consider the following options for storing a player key sets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[]string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;map[string]bool&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both options will work, but did you consider a third option of using a &lt;a href="https://en.wikipedia.org/wiki/Mask_(computing)"&gt;bitmask&lt;/a&gt;? Using a bitmask will make storing and processing keys more efficient. Once you learn the mechanics, it will be readable and maintainable as well.&lt;/p&gt;</description></item><item><title>Writing Simulations Using Go</title><link>https://www.ardanlabs.com/blog/2021/01/writing-simulations-using-go.html</link><pubDate>Wed, 13 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2021/01/writing-simulations-using-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;If you can write a for-loop, you can do statistics. - Jake Vanderplas&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A lot of developers shy away from problems which involve statistics or probability. Which is shameful since in today&amp;rsquo;s data-rich environment, you can gain a lot of insights from data.&lt;/p&gt;
&lt;p&gt;In this blog post, I&amp;rsquo;ll show you how to write a simulation tool which requires no knowledge in statistics or probability. Simulations are easy to write and can be a very effective tool in research. You only need some basic programming skills and a random number generator.&lt;/p&gt;</description></item><item><title>Working with SQLite using Go and Python</title><link>https://www.ardanlabs.com/blog/2020/11/working-with-sqlite-using-go-python.html</link><pubDate>Mon, 30 Nov 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/11/working-with-sqlite-using-go-python.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I prefer to use relational (SQL) databases in general since they provide several features that are very useful when working with data. SQLite is a great choice since the database is a single file, which makes it easier to share data. Even though it&amp;rsquo;s a single file, SQLite can handle up to 281 terabytes of data. SQLite also comes with a command line client called &lt;code&gt;sqlite3&lt;/code&gt; which is great for quick prototyping.&lt;/p&gt;</description></item><item><title>Python and Pandas : First Contact with Data</title><link>https://www.ardanlabs.com/blog/2020/11/python-pandas-first-contact-with-data.html</link><pubDate>Mon, 02 Nov 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/11/python-pandas-first-contact-with-data.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Every single company I&amp;rsquo;ve worked at and talked to has the same problem without a single exception so far - poor data quality, especially tracking data. Either there&amp;rsquo;s incomplete data, missing tracking data, duplicative tracking data.&lt;/em&gt; - DJ Patil&lt;/p&gt;
&lt;p&gt;I spend a lot of my time digging into data at various companies. Most of the time I’m surprised by what I see and so are the engineers and analysts that work at these companies. I&amp;rsquo;ve seen missing data, bad data, data nobody knows anything about, and many other oddities.&lt;/p&gt;</description></item><item><title>Generics Part 03: Struct Types and Data Semantics</title><link>https://www.ardanlabs.com/blog/2020/09/generics-03-struct-types-and-data-semantics.html</link><pubDate>Tue, 29 Sep 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/09/generics-03-struct-types-and-data-semantics.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html"&gt;Generics Part 01: Basic Syntax&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/generics-02-underlying-types.html"&gt;Generics Part 02: Underlying Types&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/generics-03-struct-types-and-data-semantics.html"&gt;Generics Part 03: Struct Types and Data Semantics&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the previous post, I showed you how to declare a user-defined type, based on an underlying type. I did this through the progression of writing different versions of the same type using concrete types, the empty interface and then finally, generics. I also provided information on how the compiler was limited in its ability to infer the substitution for the generic type during zero value construction, but it could with initialized construction.&lt;/p&gt;</description></item><item><title>Python and Go : Part IV - Using Python in Memory</title><link>https://www.ardanlabs.com/blog/2020/09/using-python-memory.html</link><pubDate>Tue, 15 Sep 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/09/using-python-memory.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html%22"&gt;Python and Go: Part I - gRPC&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html%22"&gt;Python and Go: Part II - Extending Python With Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html%22"&gt;Python and Go: Part III - Packaging Python Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/using-python-memory.html%22"&gt;Python and Go: Part IV - Using Python in Memory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In &lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html"&gt;a previous post&lt;/a&gt; we used &lt;a href="https://grpc.io/"&gt;gRPC&lt;/a&gt; to call Python code from Go. gRPC is a great framework, but there is a performance cost to it. Every function call needs to marshal the arguments using &lt;a href="https://developers.google.com/protocol-buffers"&gt;protobuf&lt;/a&gt;, make a network call over &lt;a href="https://en.wikipedia.org/wiki/HTTP/2"&gt;HTTP/2&lt;/a&gt;, and then un-marshal the result using &lt;code&gt;protobuf&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Caddy Server Acquired By Apilayer</title><link>https://www.ardanlabs.com/news/2020/08/caddy-server-is-acquired/</link><pubDate>Thu, 27 Aug 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2020/08/caddy-server-is-acquired/</guid><description>&lt;h3 id="ardan-labs-partnership-with-caddy-server-has-led-to-the-acquisition-of-the-popular-free-open-source-web-server-platform-by-apilayer"&gt;Ardan Labs partnership with Caddy Server has led to the acquisition of the popular free open-source web server platform by Apilayer.&lt;/h3&gt;
&lt;p&gt;&lt;span class='dont-break-out'&gt;&lt;a href="http://www.prweb.com/releases/caddy_server_acquired_by_apilayer/prweb17367009.htm"&gt;http://www.prweb.com/releases/caddy_server_acquired_by_apilayer/prweb17367009.htm&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Ardan Labs announces they have secured the acquisition of Caddy Server with Apilayer. Caddy is a leading open-source extensible web server platform (written in the Go programming language) that has secured trillions of network connections around the globe. Apilayer a leading provider of cloud-based API and Software-as-a-Service (SaaS) brands.
&lt;br /&gt;
&lt;br /&gt;
Matt Holt started building Caddy in 2014 as a way to provide automatic and default HTTPS support for websites. Since then, Matt and the open-source community has built Caddy to provide easy, powerful, and dynamic configuration, with an extensible framework that provides high levels of resilience. “I’m pleased to look back now and see that over 300 people have collaborated to make privacy the default for the web,” Matt explained. “We’ve raised the bar for similar products and made TLS more accessible and reliable than ever. Working with Ardan Labs and now Apilayer to continue the project has been a great boon to the open-source community.”
&lt;br /&gt;
&lt;br /&gt;
Bill Kennedy, the Managing Partner at Ardan Labs had this to say: “I am very happy for Matt, Caddy, and the Go community. I feel blessed that Ardan Labs was able to support Matt and the project at a time when it was needed most. We at Ardan always believed in Matt and the full potential of the product, and this acquisition by Apilayer shows that supporting free open-source software can result in positive outcomes. I am most thankful to Apilayer because now Caddy’s future is secure and companies can feel confident that the product will be available for many years to come.”
&lt;br /&gt;
&lt;br /&gt;
“As a developer-centric company, our leading API solutions and products are used to power automation processes for hundreds of thousands of customers, ranging from small websites, SMBs, all the way to Fortune 500 enterprises. The acquisition of Caddy brings us one step closer to the developer community, and gives us the opportunity to continue building on the innovative platform that the Caddy team has developed,&amp;quot; said Julian Zehetmayr, Founder &amp;amp; CEO of Apilayer.
&lt;br /&gt;
&lt;br /&gt;
Julian also said, “Caddy’s innovative technology and thriving open-source community were one of the most attractive elements in this partnership. Caddy will remain a separate and independent open-source brand and will continue to be directed by its original author, Matt Holt. Apilayer is committed to continued innovation, increased investment, and support for the project over the years to come.”
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Generics Part 02: Underlying Types</title><link>https://www.ardanlabs.com/blog/2020/08/generics-02-underlying-types.html</link><pubDate>Tue, 18 Aug 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/08/generics-02-underlying-types.html</guid><description>&lt;h3 id="changes"&gt;Changes&lt;/h3&gt;
&lt;p&gt;The draft is a living document which means these posts will need to change over time. This section documents when changes have taken place to this post.&lt;/p&gt;
&lt;p&gt;21/08/20 : &lt;a href="https://groups.google.com/g/golang-nuts/c/iAD0NBz3DYw/m/VcXSK55XAwAJ"&gt;Moving forward with the generics design draft&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html"&gt;Generics Part 01: Basic Syntax&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/generics-02-underlying-types.html"&gt;Generics Part 02: Underlying Types&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/generics-03-struct-types-and-data-semantics.html"&gt;Generics Part 03: Struct Types and Data Semantics&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the previous &lt;a href="https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html"&gt;post&lt;/a&gt;, I showed you how to write a generic function in Go using the proposed syntax from the generics &lt;a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md"&gt;draft&lt;/a&gt; document. I did this through the progression of writing different versions of the same function using concrete types, the empty interface, and then finally generics. I also provided information on why the new syntax was needed and how the compiler can simplify the calling of generic functions by inferring type information at the call site.&lt;/p&gt;</description></item><item><title>Python and Go : Part III - Packaging Python Code</title><link>https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html</link><pubDate>Tue, 11 Aug 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html%22"&gt;Python and Go: Part I - gRPC&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html%22"&gt;Python and Go: Part II - Extending Python With Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html%22"&gt;Python and Go: Part III - Packaging Python Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/using-python-memory.html%22"&gt;Python and Go: Part IV - Using Python in Memory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In &lt;a href="https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html"&gt;the previous post&lt;/a&gt; we compiled Go code to a shared library and used it from the Python interactive shell. In this post we&amp;rsquo;re going to finish the development process by writing a Python module that hides the low level details of working with a shared library and then package this code as a Python package.&lt;/p&gt;</description></item><item><title>Generics Part 01: Basic Syntax</title><link>https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html</link><pubDate>Thu, 23 Jul 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html</guid><description>&lt;h3 id="changes"&gt;Changes&lt;/h3&gt;
&lt;p&gt;The draft is a living document which means these posts will need to change over time. This section documents when changes have taken place to this post.&lt;/p&gt;
&lt;p&gt;21/08/20 : &lt;a href="https://groups.google.com/g/golang-nuts/c/iAD0NBz3DYw/m/VcXSK55XAwAJ"&gt;Moving forward with the generics design draft&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/07/generics-01-basic-syntax.html"&gt;Generics Part 01: Basic Syntax&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/generics-02-underlying-types.html"&gt;Generics Part 02: Underlying Types&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/generics-03-struct-types-and-data-semantics.html"&gt;Generics Part 03: Struct Types and Data Semantics&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In this series of posts about generics in Go, I will present code and teach to the different aspects of the current generics &lt;a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md"&gt;draft&lt;/a&gt;. I will provide code links with the &lt;a href="https://go2goplay.golang.org/"&gt;go2go&lt;/a&gt; playground so you can experiment with the different examples. The code samples will also be available in the Go training &lt;a href="https://github.com/ardanlabs/gotraining/tree/master/topics/go/generics"&gt;repo&lt;/a&gt;, but these examples are subject to change as I learn more or the draft changes.&lt;/p&gt;</description></item><item><title>Python and Go : Part II - Extending Python With Go</title><link>https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html</link><pubDate>Mon, 06 Jul 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html%22"&gt;Python and Go: Part I - gRPC&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html%22"&gt;Python and Go: Part II - Extending Python With Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html%22"&gt;Python and Go: Part III - Packaging Python Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/using-python-memory.html%22"&gt;Python and Go: Part IV - Using Python in Memory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In &lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html"&gt;the previous post&lt;/a&gt; we saw how a Go service can call a Python service using gRPC. Using gRPC to connect a Go and Python program together can be a great choice, but there’s a complexity price that goes with it. You need to manage one more service, deployment becomes more complex, and you need monitoring plus alerting for each service. Compared to a monolithic application, there is an order of magnitude more complexity.&lt;/p&gt;</description></item><item><title>Dgraph Database Semantics</title><link>https://www.ardanlabs.com/blog/2020/06/dgraph-database-semantics.html</link><pubDate>Fri, 26 Jun 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/06/dgraph-database-semantics.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In this &lt;a href="https://dgraph.io/paper"&gt;paper&lt;/a&gt; written by &lt;a href="https://twitter.com/manishrjain"&gt;Manish Jain&lt;/a&gt; (the founder of &lt;a href="https://dgraph.io/"&gt;Dgraph&lt;/a&gt;) he describes Dgraph as:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;a distributed graph database which provides horizontal scalability, distributed cluster-wide ACID transactions, low-latency arbitrary-depth joins, synchronous replication, high availability, and crash resilience.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are many claims being stated here which frankly I didn’t understand the meaning of the first time I read this sentence. I decided I wanted to better understand these claims with the hope that it would help me understand Dgraph’s architecture and engineering decisions better.&lt;/p&gt;</description></item><item><title>Python and Go : Part I - gRPC</title><link>https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html</link><pubDate>Mon, 08 Jun 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/06/python-go-grpc.html%22"&gt;Python and Go: Part I - gRPC&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html%22"&gt;Python and Go: Part II - Extending Python With Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/08/packaging-python-code.html%22"&gt;Python and Go: Part III - Packaging Python Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/09/using-python-memory.html%22"&gt;Python and Go: Part IV - Using Python in Memory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Like tools, programming languages tend to solve problems they are designed to. You &lt;em&gt;can&lt;/em&gt; use a knife to tighten a screw, but it&amp;rsquo;s better to use a screwdriver. Plus there is less chance of you getting hurt in the process.&lt;/p&gt;</description></item><item><title>Dgraph, GraphQL, Schemas, and CRUD</title><link>https://www.ardanlabs.com/blog/2020/05/dgraph-graphQL-schemas-crud.html</link><pubDate>Fri, 15 May 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/05/dgraph-graphQL-schemas-crud.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In most of the reviews for this post, I was asked why choose a &lt;a href="https://en.wikipedia.org/wiki/Graph_database"&gt;graph database&lt;/a&gt; over something else? This is a hard question to answer since my experience right now is limited on the graph database side. My guess is you’re wondering the same thing, so this is my best answer to date.&lt;/p&gt;
&lt;p&gt;At this point in my career, I would only choose a &lt;a href="https://en.wikipedia.org/wiki/Relational_database"&gt;relational database&lt;/a&gt; if I was writing financial software. Relational databases are very rigid so you need to really make sure you understand your data upfront. Changing the database is a big effort, but the database when designed correctly will give you very high levels of integrity and you can get good performance. These databases are hard to distribute and scale so you tend to end up with single instances that are very large and require replication for backup. The cloud providers have relational databases today that are supposed to scale, but I have no experience with them.&lt;/p&gt;</description></item><item><title>Getting Started With Dgraph and GraphQL+-</title><link>https://www.ardanlabs.com/blog/2020/04/getting-started-with-dgraph-and-graphQL+-.html</link><pubDate>Thu, 16 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/04/getting-started-with-dgraph-and-graphQL+-.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I have spent a career building business applications that work with databases, starting with SQL and then moving to No-SQL. I’ve been curious how &lt;a href="https://en.wikipedia.org/wiki/Graph_database"&gt;Graph databases&lt;/a&gt; work and how to build applications with them. It seems the sweet spot for a Graph database is when your application needs to model the interrelationships of complex and different datasets. I’ve been using No-SQL databases for these types of applications so I am super interested in knowing how Graph databases differ. After some research, I decided to learn &lt;a href="https://dgraph.io/"&gt;Dgraph&lt;/a&gt; and their modified version of &lt;a href="https://graphql.org/"&gt;GraphQL&lt;/a&gt; called &lt;a href="https://dgraph.io/docs/query-language/#graphql-fundamentals"&gt;GraphQL+-&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Modules Part 06: Vendoring</title><link>https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html</link><pubDate>Mon, 13 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;It’s no secret that I am a fan of vendoring when it’s reasonable and practical to use it for your application projects. I believe vendoring gives your application projects the most durability since the project owns every line of source code it needs to build the applications. If you want a reproducible build without needing to rely on external services (like module mirrors) and being connected to the network, vendoring is the solution.&lt;/p&gt;</description></item><item><title>Modules Part 05: Gopls Improvements</title><link>https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html</link><pubDate>Wed, 08 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;This is a guest post written by Rohan Challa, a member of the Go team working on gopls.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This document is a follow up to Bill Kennedy’s &lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt; post&lt;/a&gt; on projects, dependencies and &lt;code&gt;gopls&lt;/code&gt;. His post showed that &lt;a href="https://github.com/golang/tools/blob/master/gopls/doc/user.md"&gt;&lt;code&gt;gopls&lt;/code&gt;&lt;/a&gt; did not work well with modules, particularly when adding and removing dependencies from a project inside of your editor. Over the last 3 months, my work on the Go tools team has involved improving support for modules in &lt;code&gt;gopls&lt;/code&gt; .&lt;/p&gt;</description></item><item><title>Docker Images : Part III - Going Farther To Reduce Image Size</title><link>https://www.ardanlabs.com/blog/2020/04/docker-images-part3-going-farther-reduce-image-size.html</link><pubDate>Fri, 03 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/04/docker-images-part3-going-farther-reduce-image-size.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html%22"&gt;Reducing Image Size&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part2-details-specific-to-different-languages.html%22"&gt;Details Specific To Different Languages&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/docker-images-part3-going-farther-reduce-image-size.html%22"&gt;Going Farther To Reduce Image Size&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first two parts of this series, we covered the most common methods to optimize Docker image size. We saw how multi-stage builds,
combined with Alpine-based images, and sometimes static builds, would generally give us the most dramatic savings. In this last part, we will see how to go even farther. We will talk about standardizing base images, stripping binaries, assets optimization, and other build systems or add-ons like DockerSlim or Bazel, as well as the NixOS distribution.&lt;/p&gt;</description></item><item><title>Docker Images : Part II - Details Specific To Different Languages</title><link>https://www.ardanlabs.com/blog/2020/02/docker-images-part2-details-specific-to-different-languages.html</link><pubDate>Mon, 24 Feb 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/02/docker-images-part2-details-specific-to-different-languages.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html%22"&gt;Reducing Image Size&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part2-details-specific-to-different-languages.html%22"&gt;Details Specific To Different Languages&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/docker-images-part3-going-farther-reduce-image-size.html%22"&gt;Going Farther To Reduce Image Size&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first part, we introduced multi-stage builds, static and dynamic linking, and briefly mentioned Alpine. In this second part, we are going to dive into some details specific to Go. Then we will talk more about Alpine, because it&amp;rsquo;s worth it; and finally we will see how things play out with other languages like Java, Node, Python, Ruby, and Rust.&lt;/p&gt;</description></item><item><title>Modules Part 04: Mirrors, Checksums and Athens</title><link>https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html</link><pubDate>Mon, 10 Feb 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;One of the longer standing questions I had when first learning about modules was how the module mirror, checksum database and Athens worked. The Go team has written extensively about the module mirror and checksum database, but I hope to consolidate the most important information here. In this post, I provide the purpose of these systems, the different configuration options you have, and show these systems in action using example programs.&lt;/p&gt;</description></item><item><title>Docker Images : Part I - Reducing Image Size</title><link>https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html</link><pubDate>Tue, 04 Feb 2020 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html%22"&gt;Reducing Image Size&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/docker-images-part2-details-specific-to-different-languages.html%22"&gt;Details Specific To Different Languages&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/docker-images-part3-going-farther-reduce-image-size.html%22"&gt;Going Farther To Reduce Image Size&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;When getting started with containers, it&amp;rsquo;s pretty easy to be shocked by the size of the images that we build. We&amp;rsquo;re going to review a number of techniques to reduce image size, without sacrificing developers&amp;rsquo; and ops&amp;rsquo; convenience. In this first part, we will talk about multi-stage builds, because that&amp;rsquo;s where anyone should start if they want to reduce the size of their images. We will also explain the differences between static and dynamic linking, as well as why we should care about that. This will be the occasion to introduce Alpine.&lt;/p&gt;</description></item><item><title>Modules Part 03: Minimal Version Selection</title><link>https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html</link><pubDate>Wed, 18 Dec 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Every dependency management solution has to solve the problem of picking a version of a dependency. Many of the version selection algorithms that exist today attempt to identify the “latest greatest” version of any dependency. This makes sense if you believe semantic versioning will be applied correctly and the social contract will be respected. In these cases, the “latest greatest” version of a dependency should be the most stable and secure version and should have backwards compatibility with earlier versions. At least in the same major version dependency tree.&lt;/p&gt;</description></item><item><title>Modules Part 02: Projects, Dependencies and Gopls</title><link>https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html</link><pubDate>Mon, 02 Dec 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Modules is the system integrated into Go to provide support for dependency management. This means modules touch just about anything related to working with source code, including editor support. To provide editors with support for modules (and for other reasons), the Go team built a service named &lt;a href="https://github.com/golang/tools/blob/master/gopls/doc/user.md"&gt;gopls&lt;/a&gt; which implements the language server protocol (&lt;a href="https://microsoft.github.io/language-server-protocol/"&gt;LSP&lt;/a&gt;). LSP was originally developed by Microsoft for VS Code and has become an open standard. The idea of the protocol is to provide editors with support for language features such as auto complete, go to definition, and find all references.&lt;/p&gt;</description></item><item><title>Flutter: Forbes had it right</title><link>https://www.ardanlabs.com/blog/2019/11/flutter-forbes-had-it-right.html</link><pubDate>Sat, 16 Nov 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/11/flutter-forbes-had-it-right.html</guid><description>&lt;p&gt;&lt;em&gt;“Flutter and Fuchsia. In 2019 you will see these two words everywhere, and now is your chance to get ahead of the curve.” - Todd Fabacher, writing for Forbes&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Forbes saw it coming back in July of 2018. If you didn’t, then here’s your chance to find out why they did. From lower lead times to increased productivity, the number of platforms you’ll be able to reach to the simplicity of maintenance, Flutter is now leading the way in just about every category.&lt;/p&gt;</description></item><item><title>Modules Part 01: Why And What</title><link>https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html</link><pubDate>Thu, 10 Oct 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html</guid><description>&lt;h3 id="series-index"&gt;Series Index&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2019/10/modules-01-why-and-what.html"&gt;Why and What&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-02-projects-dependencies-gopls.html"&gt;Projects, Dependencies and Gopls&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2019/12/modules-03-minimal-version-selection.html"&gt;Minimal Version Selection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/02/modules-04-mirros-checksums-athens.html"&gt;Mirrors, Checksums and Athens&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-05-gopls-improvements.html"&gt;Gopls Improvements&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html"&gt;Vendoring&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Modules provide an integrated solution for three key problems that have been a pain point for developers since Go’s initial release:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ability to work with Go code outside of the GOPATH workspace.&lt;/li&gt;
&lt;li&gt;Ability to version a dependency and identify the most compatible version to use.&lt;/li&gt;
&lt;li&gt;Ability to manage dependencies natively using the Go tooling.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the release of Go 1.13, these three problems are a thing of the past. It has taken a lot of engineering effort from the Go team over the past 2 years to get everyone here. In this post, I will focus on the transition from GOPATH to modules and the problems modules are solving. Along the way, I will provide just enough of the semantics so you can have a better understanding of how modules work at a high level. Maybe more importantly, why they work the way they do.&lt;/p&gt;</description></item><item><title>Integration Testing in Go: Part II - Set-up and Writing Tests</title><link>https://www.ardanlabs.com/blog/2019/10/integration-testing-in-go-set-up-and-writing-tests.html</link><pubDate>Thu, 03 Oct 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/10/integration-testing-in-go-set-up-and-writing-tests.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is the 2nd installment of a 2 part series about integration testing. You can read the first &lt;a href="https://www.ardanlabs.com/blog/2019/03/integration-testing-in-go-executing-tests-with-docker.html"&gt;installment&lt;/a&gt;, which is about executing tests in a restricted environment using Docker. The example repository that this post draws it examples from can be found &lt;a href="https://github.com/george-e-shaw-iv/integration-tests-example"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;”More than the act of testing, the act of designing tests is one of the best bug preventers known.” - &lt;em&gt;Boris Beizer&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before an integration test can be executed, the external systems that the test will be touching must be properly configured. If not, the test results will not be valid or reliable. For example, a database needs to be loaded with well defined data that is correct for the behavior being tested. Data updated during a test needs to be validated, especially if that updated data is required to be accurate for a subsequent test.&lt;/p&gt;</description></item><item><title>Why is DevOps Important?</title><link>https://www.ardanlabs.com/blog/2019/08/devops-questions-for-ardan-labs.html</link><pubDate>Mon, 26 Aug 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/08/devops-questions-for-ardan-labs.html</guid><description>&lt;h3 id="1-what-are-four-keys-for-great-devops"&gt;1. What are four keys for great DevOps?&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Collaboration:&lt;/b&gt; DevOps requires collaboration, both within teams and between teams. Good communication between teams implies to break down silos, which can be harder than it sounds in organizations where a leader and their team are rewarded for individual achievements, discouraging them from collaborating and sharing information with others, and often encouraging politics at the expense of the company&amp;rsquo;s success.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Blameless Culture:&lt;/b&gt; It also requires to internalize that we learn from our failures. Instead of promoting a culture where mistakes can seriously hinder one&amp;rsquo;s career and are therefore often shoved under the rug, we need to embrace a blameless culture where each failure becomes an opportunity to improve, and improve continuously.&lt;/p&gt;</description></item><item><title>Caddy Partnership With Light Code Labs</title><link>https://www.ardanlabs.com/blog/2019/07/caddy-partnership-light-code-labs.html</link><pubDate>Mon, 22 Jul 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/07/caddy-partnership-light-code-labs.html</guid><description>&lt;p&gt;Ardan Labs (a leader in building Go enterprise software) is excited to announce that we have partnered with &lt;a href="https://lightcodelabs.com/"&gt;Light Code Labs&lt;/a&gt; and &lt;a href="https://twitter.com/mholt6"&gt;Matt Holt&lt;/a&gt; to bring &lt;a href="https://caddyserver.com/"&gt;Caddy&lt;/a&gt; into the Ardan Labs family of products and services. Caddy is a lightweight ingress service written in Go that provides automated security features and a plugin environment for extensibility. With the service being free open source (FOSS), small and large Go engineering teams finally have the ability to own and maintain their ingress and load balancing software with ease. We believe the Caddy project is as important as Docker and Kubernetes in maintaining a solid and scalable production environment.&lt;/p&gt;</description></item><item><title>An Open Letter To The Go Team About Try</title><link>https://www.ardanlabs.com/blog/2019/07/an-open-letter-to-the-go-team-about-try.html</link><pubDate>Mon, 01 Jul 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/07/an-open-letter-to-the-go-team-about-try.html</guid><description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;“Once a language gets complex enough, programming in it is more like carving out a subset from an infinite sea of features, most of which we’ll never learn. Once a language feels infinite, the costs of adding further features to it are no longer apparent&amp;quot;. - [Mark Miller]
(&lt;a href="https://medium.com/@erights/the-tragedy-of-the-common-lisp-why-large-languages-explode-4e83096239b9)"&gt;https://medium.com/@erights/the-tragedy-of-the-common-lisp-why-large-languages-explode-4e83096239b9)&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The new &lt;code&gt;try&lt;/code&gt; proposal is an addition to the language that introduces a second mechanic to handle errors. It is being introduced in response to data gathered from the &lt;a href="https://blog.golang.org/survey2018-results"&gt;2018 Go Survey&lt;/a&gt; and a review of proposals that were submitted during the &lt;a href="https://blog.golang.org/go2-here-we-come"&gt;Go 2 proposal process&lt;/a&gt;. The conclusion the Go team made from these data gathering exercises was that Go developers wanted better error handling.&lt;/p&gt;</description></item><item><title>Ardan Labs Partners With the Popular Open-Source Project, Caddy Web Server.</title><link>https://www.ardanlabs.com/news/2019/05/ardan-labs-partners-with-caddy.html</link><pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2019/05/ardan-labs-partners-with-caddy.html</guid><description>&lt;p&gt;Ardan Labs will work with the Caddy team on bringing a highly functional enterprise version to market&lt;/p&gt;
&lt;p&gt;Caddy Enterprise
We have recently agreed on terms for a partnership which will allow us to develop Caddy side-by-side with the founding team. Caddy is an incredible open-source project that has become the premier automatic HTTPS web server on the market.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../../images/news/caddy-banner.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Over the past few years, the project has grown tremendously and even attracted some large enterprise users. This has prompted Caddy to expand their capabilities and partner with Ardan Labs to help develop and support Caddy Enterprise.
Some of the features we are working on are:&lt;/p&gt;</description></item><item><title>Ardan Labs Announces New Division Focused Solely on Kubernetes</title><link>https://www.ardanlabs.com/news/2019/05/ardan-labs-announces-new-kubernetes-division.html</link><pubDate>Mon, 27 May 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/news/2019/05/ardan-labs-announces-new-kubernetes-division.html</guid><description>&lt;p&gt;The new line of services will include Kubernetes Training Workshops and Kubernetes Consulting Services.&lt;/p&gt;
&lt;p&gt;Ardan Labs has partnered with Jérôme Petazzoni to lead our Kubernetes training and consulting division. Jérôme was part of the team that built, scaled, and operated the dotCloud PAAS, before that company became Docker.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../../images/news/kubernetes-banner.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Here are some things to know about Jérôme:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;He has spent seven years working at Docker, where he’s worn countless hats and ran containers in production before it was cool.&lt;/li&gt;
&lt;li&gt;He loves to share his knowledge, which has led him to become a speaker that has now given hundreds of talks and demos on containers, Docker, and Kubernetes.&lt;/li&gt;
&lt;li&gt;He has trained thousands of people to deploy their apps with confidence on these platforms and continues to do so as an independent consultant.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are extremely excited about this partnership because it will allow our customers to access the same top-notch training they are used to in GO for Kubernetes.&lt;/p&gt;</description></item><item><title>Concurrency Trap #2: Incomplete Work</title><link>https://www.ardanlabs.com/blog/2019/04/concurrency-trap-2-incomplete-work.html</link><pubDate>Thu, 18 Apr 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/04/concurrency-trap-2-incomplete-work.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In my first post on &lt;a href="https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html"&gt;Goroutine Leaks&lt;/a&gt;, I mentioned that concurrency is a useful tool but it comes with certain traps that don&amp;rsquo;t exist in synchronous programs. To continue with this theme, I will introduce a new trap called incomplete work. Incomplete work occurs when a program terminates before outstanding Goroutines (non-main goroutines) complete. Depending on the nature of the Goroutine that is being terminated forcefully, this may be a serious problem.&lt;/p&gt;</description></item><item><title>Integration Testing in Go: Part I - Executing Tests with Docker</title><link>https://www.ardanlabs.com/blog/2019/03/integration-testing-in-go-executing-tests-with-docker.html</link><pubDate>Mon, 18 Mar 2019 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2019/03/integration-testing-in-go-executing-tests-with-docker.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Testing leads to failure, and failure leads to understanding.” - &lt;em&gt;Burt Rutan&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Burt Rutan is an aerospace engineer who designed Voyager, the first plane to fly around the world without stopping or refueling. Although Rutan was not a software engineer, his words speak volumes to the importance of testing, even testing software. Testing software in all forms is extremely important, whether it be unit, integration, system, or acceptance testing. However, depending on the project, one form of testing can be more valuable than the others. In other words, sometimes one form of testing can lead to better understanding about the health and integrity of the software than the other forms.&lt;/p&gt;</description></item><item><title>Goroutine Leaks - The Abandoned Receivers</title><link>https://www.ardanlabs.com/blog/2018/12/goroutine-leaks-the-abandoned-receivers.html</link><pubDate>Wed, 19 Dec 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/12/goroutine-leaks-the-abandoned-receivers.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Goroutine Leaks are a common cause of memory leaks in Go programs. In my &lt;a href="https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html"&gt;previous post&lt;/a&gt;, I presented an introduction to Goroutine leaks and provided one example of a common mistake that many Go developers make. Continuing that work, this post presents another scenario on how Goroutines could be leaked.&lt;/p&gt;
&lt;h3 id="leak-the-abandoned-receivers"&gt;Leak: The Abandoned Receivers&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;For this leak example you will see multiple Goroutines blocked waiting to receive values that will never be sent.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Goroutine Leaks - The Forgotten Sender</title><link>https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html</link><pubDate>Mon, 12 Nov 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Concurrent programming allows developers to solve problems using more than one path of execution and is often used in an attempt to improve performance. Concurrency doesn’t mean these multiple paths are executing in parallel; it means these paths are executing out-of-order instead of sequentially. Historically, this type of programming is facilitated using libraries that are either provided by a standard library or from 3rd party developers.&lt;/p&gt;
&lt;p&gt;In Go, concurrency features like Goroutines and channels are built into the language and runtime to reduce or eliminate the need for libraries. This has created the illusion that writing concurrent programs in Go is easy. You must be cautious when deciding to use concurrency as it comes with some unique side effects or traps if not used correctly. These traps can create complexity and nasty bugs if you’re not careful.&lt;/p&gt;</description></item><item><title>Creating the Art for Gopher Kart</title><link>https://www.ardanlabs.com/blog/2018/08/creating-the-art-for-gopher-kart.html</link><pubDate>Tue, 14 Aug 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/08/creating-the-art-for-gopher-kart.html</guid><description>&lt;p&gt;&lt;img src="../../../images/gopher-kart/intro-image.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;In the months leading up to GopherCon, my wife &lt;a href="https://twitter.com/jamiletmzelaya" target="_blank"&gt;Jamilet&lt;/a&gt; and I had come up with the idea of creating a “small” browser-based game for the convention using the racing theme. Neither of us had ever worked on a game before and we had no idea what was involved. However, we knew we wanted to design and build something special for the awesome Gopher community.&lt;/p&gt;
&lt;p&gt;The original idea was to create a game where Gophers raced each other around a track. We looked into how much time that would take and realized working part time meant we wouldn’t finish the game in time. So we decided to build a game that was simpler and settled on a coin collection game.&lt;/p&gt;</description></item><item><title>Ultimate Go Service</title><link>https://www.ardanlabs.com/blog/2018/06/ultimate-go-service.html</link><pubDate>Wed, 27 Jun 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/06/ultimate-go-service.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I teach a class called &lt;a href="https://twitter.com/hashtag/ultimatego?src=hash"&gt;Ultimate Go&lt;/a&gt;. The class is three days long and teaches you the history, mechanics and semantics of the Go programming language. The idea is to teach you how to read code to the level that you can understand the behavior and impact your program is having on the machine. This helps you make better and more consistent engineering decisions.&lt;/p&gt;
&lt;p&gt;At the same time, the class is very focused on teaching you how to optimize for correctness so the code you are writing is readable as a first priority. After three days in the class, I do believe you are a better developer. Not just a better Go developer, but a better developer in general. This is regardless of how much experience you had in Go or programming before you walked in the room.&lt;/p&gt;</description></item><item><title>Bounds Check Elimination In Go</title><link>https://www.ardanlabs.com/blog/2018/04/bounds-check-elimination-in-go.html</link><pubDate>Sat, 28 Apr 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/04/bounds-check-elimination-in-go.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;One day I was talking to &lt;a href="https://twitter.com/dgryski"&gt;Damian Gryski&lt;/a&gt; in Slack about some performance improvements he made to his &lt;a href="https://github.com/dgryski/go-metro"&gt;go-metro&lt;/a&gt; package. When I first looked at the changes I was completely confused how this could have any effect on the performance of the code. I felt the code was more readable, but more performant? I didn’t see it.&lt;/p&gt;
&lt;p&gt;Then Damian started to talk to me about a compiler optimization called Bounds Check Elimination or BCE. The idea behind BCE is to give the compiler hints that index-based memory access is guaranteed to be safe and therefore the compiler didn’t have to add extra code to check the memory access at runtime. The safe elimination of these integrity checks can help improve performance.&lt;/p&gt;</description></item><item><title>Interface Values Are Valueless</title><link>https://www.ardanlabs.com/blog/2018/03/interface-values-are-valueless.html</link><pubDate>Fri, 23 Mar 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/03/interface-values-are-valueless.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I’ve been seeing a lot of question about interfaces lately on Slack. Most of the time the answers are technical and focus on implementation details. Implementation is important to help with debugging, but implementation doesn’t help with design. When it comes to designing code with interfaces, behavior has to be the main focus.&lt;/p&gt;
&lt;p&gt;In this post, I hope to provide a different way to think about interfaces and how to design code with them. I want you to stop focusing on the implementation details and focus on the relationship interfaces have with concrete data.&lt;/p&gt;</description></item><item><title>Focus On Being Precise</title><link>https://www.ardanlabs.com/blog/2018/02/focus-on-being-precise.html</link><pubDate>Tue, 20 Feb 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/02/focus-on-being-precise.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I was guided for many years to write functions that are generalized and to create layers upon layers of abstraction so things don’t break as business requirements change. That the cost of breaking a function signature, for example, is expensive and something that should be avoided. Therefore, write functions that take more generic parameters or hide things in a receiver or context to be less prone to breakage.&lt;/p&gt;
&lt;p&gt;On the surface this seems like a good and reasonable idea. However, I have come to believe that this practice leads to engineering problems that I consider to be much worse than the supposed benefit. For private code bases, which is the majority of the code I work on, breaking an API should be encouraged if it will make the code base better. It’s better to refactor and keep the code base clear than to head down a path of legacy code.&lt;/p&gt;</description></item><item><title>Escape-Analysis Flaws</title><link>https://www.ardanlabs.com/blog/2018/01/escape-analysis-flaws.html</link><pubDate>Mon, 22 Jan 2018 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2018/01/escape-analysis-flaws.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;It will be helpful to read this four-part series first on escape analysis and data semantics. Details on how to read an escape analysis report and pprof output have been outlined here.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Even after working with Go for 4 years, I am continually amazed by the language. Thanks to the static code analysis the compiler performs, the compiler can apply interesting optimizations to the code it produces. One type of analysis the compiler performs is called escape analysis. This produces optimizations and simplifications around memory management.&lt;/p&gt;</description></item><item><title>The Behavior Of Channels</title><link>https://www.ardanlabs.com/blog/2017/10/the-behavior-of-channels.html</link><pubDate>Tue, 24 Oct 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/10/the-behavior-of-channels.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;When I started to work with Go’s channels for the first time, I made the mistake of thinking about channels as a data structure. I saw channels as a queue that provided automatic synchronized access between goroutines. This structural understanding caused me to write a lot of bad and complicated concurrent code.&lt;/p&gt;
&lt;p&gt;I learned over time that it’s best to forget about how channels are structured and focus on how they behave. So now when it comes to channels, I think about one thing: &lt;strong&gt;signaling&lt;/strong&gt;. A channel allows one goroutine to signal another goroutine about a particular event. Signaling is at the core of everything you should be doing with channels. Thinking of channels as a signaling mechanism will allow you to write better code with well defined and more precise behavior.&lt;/p&gt;</description></item><item><title>Interface Semantics</title><link>https://www.ardanlabs.com/blog/2017/07/interface-semantics.html</link><pubDate>Sat, 15 Jul 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/07/interface-semantics.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;If you want to put this post in some better context, I suggest reading the following series of posts, which lay out some other fundamental and relevant design principles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In particular, the idea of value and pointer semantics is everywhere in the Go programming language. As stated in those earlier posts, semantic consistency is critical for integrity and readability. It allows developers to maintain a strong mental model of a code base as it continues to grow. It also helps to minimize mistakes, side effects, and unexpected behavior.&lt;/p&gt;</description></item><item><title>For Range Semantics</title><link>https://www.ardanlabs.com/blog/2017/06/for-range-semantics.html</link><pubDate>Tue, 27 Jun 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/06/for-range-semantics.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;These are good posts to read first to better understand the material presented in this post:&lt;/p&gt;
&lt;p&gt;Index of the four part series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The idea of value and pointer semantics are everywhere in the Go programming language. As stated before in those earlier posts, semantic consistency is critical for integrity and readability. It allows developers to maintain a strong mental model of a code base as it continues to grow. It also helps to minimize mistakes, side effects, and unknown behavior.&lt;/p&gt;</description></item><item><title>Design Philosophy On Data And Semantics</title><link>https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html</link><pubDate>Thu, 08 Jun 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This is the final post in a four part series discussing the mechanics and design behind pointers, stacks, heaps, escape analysis and value/pointer semantics in Go. This post focuses on data and the design philosophies of applying value/pointer semantics in your code.&lt;/p&gt;
&lt;p&gt;Index of the four part series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="design-philosophies"&gt;Design Philosophies&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;ldquo;Value semantics keep values on the stack, which reduces pressure on the Garbage Collector (GC). However, value semantics require various copies of any given value to be stored, tracked and maintained. Pointer semantics place values on the heap, which can put pressure on the GC. However, pointer semantics are efficient because only one value needs to be stored, tracked and maintained.&amp;rdquo; - Bill Kennedy&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Language Mechanics On Memory Profiling</title><link>https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html</link><pubDate>Thu, 01 Jun 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This is the third post in a four part series that will provide an understanding of the mechanics and design behind pointers, stacks, heaps, escape analysis and value/pointer semantics in Go. This post focuses on heaps and escape analysis.&lt;/p&gt;
&lt;p&gt;Index of the four part series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Watch this video to see a live demo of this code:&lt;br&gt;
&lt;a href="https://engineers.sg/video/go-concurrency-live-gophercon-sg-2017--1746"&gt;GopherCon Singapore (2017) - Escape Analysis&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Language Mechanics On Escape Analysis</title><link>https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html</link><pubDate>Fri, 26 May 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This is the second post in a four part series that will provide an understanding of the mechanics and design behind pointers, stacks, heaps, escape analysis and value/pointer semantics in Go. This post focuses on heaps and escape analysis.&lt;/p&gt;
&lt;p&gt;Index of the four part series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the first post in this four part series, I taught the basics of pointer mechanics by using an example in which a value was shared down a goroutine’s stack. What I did not show you is what happens when you share a value up the stack. To understand this, you need to learn about another area of memory where values can live: the &amp;ldquo;heap&amp;rdquo;. With that knowledge, you can then begin to learn about &amp;ldquo;escape analysis&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Language Mechanics On Stacks And Pointers</title><link>https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html</link><pubDate>Thu, 18 May 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This is the first post in a four part series that will provide an understanding of the mechanics and design behind pointers, stacks, heaps, escape analysis and value/pointer semantics in Go. This post focuses on stacks and pointers.&lt;/p&gt;
&lt;p&gt;Index of the four part series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html"&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html"&gt;Language Mechanics On Escape Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/language-mechanics-on-memory-profiling.html"&gt;Language Mechanics On Memory Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html"&gt;Design Philosophy On Data And Semantics&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I’m not going to sugar coat it, pointers are difficult to comprehend. When used incorrectly, pointers can produce nasty bugs and even performance issues. This is especially true when writing concurrent or multi-threaded software. It’s no wonder so many languages attempt to hide pointers away from programmers. However, if you are writing software in Go, there is no way for you to avoid them. Without a strong understanding of pointers, you will struggle to write clean, simple and efficient code.&lt;/p&gt;</description></item><item><title>Design Philosophy On Logging</title><link>https://www.ardanlabs.com/blog/2017/05/design-philosophy-on-logging.html</link><pubDate>Wed, 10 May 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/05/design-philosophy-on-logging.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is part of a series designed to make you think about your own design philosophy on different topics. If you haven’t read the following post yet, please do so first:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html"&gt;Develop Your Design Philosophy&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Systems cannot be developed assuming that human beings will be able to write millions of lines of code without making mistakes, and debugging alone is not an efficient way to develop reliable systems. - Al Aho (inventor of AWK)&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Package Oriented Design</title><link>https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html</link><pubDate>Fri, 24 Feb 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html</guid><description>&lt;p&gt;&lt;em&gt;Updated on February 28th, 2017&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is part of a series of posts designed to make you think about your own design philosophy on different topics. If you haven’t read these posts yet, please do so first:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html"&gt;Develop Your Design Philosophy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2017/02/design-philosophy-on-packaging.html"&gt;Design Philosophy On Packaging&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Package Oriented Design allows a developer to identify where a package belongs inside a Go project and the design guidelines the package must respect. It defines what a Go project is and how a Go project is structured. Finally, it improves communication between team members and promotes clean package design and project architecture that is discussable.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Design Philosophy On Packaging</title><link>https://www.ardanlabs.com/blog/2017/02/design-philosophy-on-packaging.html</link><pubDate>Mon, 20 Feb 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/02/design-philosophy-on-packaging.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is part of a series of posts designed to make you think about your own design philosophy on different topics. If you haven’t read this post yet, please do so first:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html"&gt;Develop Your Design Philosophy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After this post, read this next one:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html"&gt;Package Oriented Design&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In an &lt;a href="http://www.cs.cmu.edu/~mihaib/kernighan-interview/index.html"&gt;interview&lt;/a&gt; given to Brian Kernighan by Mihai Budiu in the year 2000, Brian was asked the following question:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;“Can you tell us about the worse features of C, from your point of view”?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Design Philosophy On Integrity</title><link>https://www.ardanlabs.com/blog/2017/02/design-philosophy-on-integrity.html</link><pubDate>Tue, 07 Feb 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/02/design-philosophy-on-integrity.html</guid><description>&lt;p&gt;&lt;em&gt;Updated on February 10th, 2017&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is part of a series of posts designed to make you think about your own design philosophy on different topics. If you haven’t read this post yet, please do so first:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html"&gt;Develop Your Design Philosophy&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I want to share with you my design philosophy around the word &lt;code&gt;Integrity&lt;/code&gt; and what it means to me from a Go perspective. Integrity is much more than just a buzzword, it is a driving principle in everything I do, both in code and in life.&lt;/p&gt;</description></item><item><title>Develop Your Design Philosophy</title><link>https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html</link><pubDate>Tue, 31 Jan 2017 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2017/01/develop-your-design-philosophy.html</guid><description>&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;This post is part of a series of posts designed to make you think about your own design philosophy on different topics. I will not be laying out direct examples to prove my own thoughts and ideas. It takes me two or three days in the classroom to do that and it’s why I think my &lt;a href="https://github.com/ardanlabs/gotraining#current-schedule"&gt;classes&lt;/a&gt; are so special.&lt;/p&gt;
&lt;p&gt;My goal is to get you and others to write the next set of blog posts to prove or disprove these ideas. If you do, then you will be starting a journey of developing your own design philosophy and how brilliant is that.&lt;/p&gt;</description></item><item><title>Video: Design Philosophy in Go</title><link>https://www.ardanlabs.com/blog/2016/12/developing-a-design-philosophy-in-go.html</link><pubDate>Mon, 05 Dec 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/12/developing-a-design-philosophy-in-go.html</guid><description>&lt;p&gt;This is a talk that I gave at the Vancouver Meetup on November 29th, 2016. The talk covers topics around developing your own design philosophy with a focus on decoupling from change. These are things I cover extensively in the &lt;a href="https://github.com/ardanlabs/gotraining#go-training"&gt;Ultimate Go Classes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href="https://www.ardanlabs.com/broken-link"&gt;material&lt;/a&gt; that is covered in the talk. Review the &lt;code&gt;Grouping&lt;/code&gt; and &lt;code&gt;Decoupling&lt;/code&gt; topics.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=7YcLIbG1ekM&amp;amp;feature=youtu.be"&gt;&lt;img src="../../../images/goinggo/post_74.jpg" alt="ScreenShot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Application Focused API Design</title><link>https://www.ardanlabs.com/blog/2016/11/application-focused-api-design.html</link><pubDate>Thu, 03 Nov 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/11/application-focused-api-design.html</guid><description>&lt;p&gt;&lt;em&gt;“I think it&amp;rsquo;s ok to do heinous stuff to test an API if it makes it more usable by others.” - Nate Finch&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="prelude"&gt;Prelude&lt;/h3&gt;
&lt;p&gt;If you are new to Go, it might help to read these posts first before continuing on with this post.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html"&gt;https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2015/09/composition-with-go.html"&gt;https://www.ardanlabs.com/blog/2015/09/composition-with-go.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2016/10/reducing-type-hierarchies.html"&gt;https://www.ardanlabs.com/blog/2016/10/reducing-type-hierarchies.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.ardanlabs.com/blog/2016/10/avoid-interface-pollution.html"&gt;https://www.ardanlabs.com/blog/2016/10/avoid-interface-pollution.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Packages exists to help provide support for specific problems that are commonly found in the different applications we are building. A package API should be intuitive and simple to use so application developers can focus on their concerns and hopefully develop their applications faster. Tests are an artifact of development and exist to make sure the code we are writing has integrity before it is published. Tests are not a part of the application. They do not get built with the application and none of that code runs when the application is running.&lt;/p&gt;</description></item><item><title>Avoid Interface Pollution</title><link>https://www.ardanlabs.com/blog/2016/10/avoid-interface-pollution.html</link><pubDate>Fri, 21 Oct 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/10/avoid-interface-pollution.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Interfaces should only be used when their added value is clear. I see too many packages that declare interfaces unnecessarily, sometimes just for the sake of using interfaces. The use of interfaces when they are not necessary is called interface pollution. This is a practice I would like to see questioned and identified more in code reviews.&lt;/p&gt;
&lt;h3 id="code-example"&gt;Code Example&lt;/h3&gt;
&lt;p&gt;Let’s look at a code example that contains questionable design choices that raise flags for interface pollution.&lt;/p&gt;</description></item><item><title>Reducing Type Hierarchies</title><link>https://www.ardanlabs.com/blog/2016/10/reducing-type-hierarchies.html</link><pubDate>Sun, 09 Oct 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/10/reducing-type-hierarchies.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I see a lot of developers coming to Go from object oriented programming languages such as C# and Java. Because these developers have been trained to use &lt;a href="http://bit.ly/1IR9T9j"&gt;type hierarchies&lt;/a&gt;, it makes sense for them to use this same pattern in Go. However, there are aspects of Go that don’t allow type hierarchies to provide the same level of functionality they do in other object oriented programming languages. Specifically, the concepts of base types and subtyping don’t exist in Go so type reuse requires a different way of thinking.&lt;/p&gt;</description></item><item><title>Installing Go And Your Workspace</title><link>https://www.ardanlabs.com/blog/2016/05/installing-go-and-your-workspace.html</link><pubDate>Thu, 12 May 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/05/installing-go-and-your-workspace.html</guid><description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;If you are new to Linux or the Mac you might find installing Go to be a bit confusing. It was for me when I started learning Go. Go was the reason I stopped using Windows, which I used for 20 years. Even if you&amp;rsquo;re experienced with these operation systems, setting up Go might seem a bit of a mystery. With this in mind, let&amp;rsquo;s walk through installing Go.&lt;/p&gt;</description></item><item><title>Copying Interface Values In Go</title><link>https://www.ardanlabs.com/blog/2016/05/copying-interface-values-in-go.html</link><pubDate>Thu, 05 May 2016 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2016/05/copying-interface-values-in-go.html</guid><description>&lt;p&gt;I am constantly thinking about the Go language and how things work. Lately I have been thinking how everything in Go is by value. We see this when we pass values to functions, when we iterate over slices and when we perform type assertions. In every case, copies of the values that are stored in these data structures are returned. When I first started learning Go this threw me off, but I have come to appreciate the reasonability this brings to our code.&lt;/p&gt;</description></item><item><title>Composition with Go</title><link>https://www.ardanlabs.com/blog/2015/09/composition-with-go.html</link><pubDate>Sun, 13 Sep 2015 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2015/09/composition-with-go.html</guid><description>&lt;p&gt;Composition goes beyond the mechanics of &lt;a href="https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html" target="_blank"&gt;type embedding&lt;/a&gt;. It&amp;rsquo;s a paradigm we can leverage to design better APIs and to build larger programs from smaller parts. It all starts from the declaration and implementation of types that have a single purpose. Programs that are architected with composition in mind have a better chance to grow and adapt to changing needs. They are also much easier to read and reason about.&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate these concepts, we will be reviewing the following program:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://github.com/ardanlabs/gotraining/blob/c081f15e59fbe895c50b25a8a2d2eaf7a5772cbc/topics/composition/example4/example4.go" target="_blank"&gt;Sample Code&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This code sample explores the mechanics behind embedding and provides us with an opportunity to discuss how, with composition, we can design for both flexibility and readability. Every identifier that is exported from a package makes up the package’s API. This includes all the constants, variables, types, methods and functions that are exported. Comments are a frequently-overlooked aspect of every package's API, so be very clear and concise when communicating information to the user of the package.&lt;br /&gt;
&lt;br /&gt;
The example is long so let’s break it down in pieces and walk our way through it.&lt;br /&gt;
&lt;br /&gt;
The idea behind this program is we have a contractor that we hired to renovate our house. In particular, there are some boards in the house that have rotted and need to be yanked out, as well as new boards that need to be nailed in. The contractor will be given a supply of nails, boards to work with and tools to perform the work.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 1&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
13 // Board represents a surface we can work on.&lt;br /&gt;
14 type Board struct {&lt;br /&gt;
15 &amp;nbsp; &amp;nbsp; NailsNeeded int&lt;br /&gt;
16 &amp;nbsp; &amp;nbsp; NailsDriven int&lt;br /&gt;
17 }
&lt;/div&gt;
&lt;br /&gt;
In listing 1, we have the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Board&lt;/span&gt; type. A &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Board&lt;/span&gt; has two fields, the number of nails the board needs and the current number of nails driven into the board. Now, let’s look at the interfaces that are declared:
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 2&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
21 // NailDriver represents behavior to drive nails into a board.&lt;br /&gt;
22 type NailDriver interface {&lt;br /&gt;
23 &amp;nbsp; &amp;nbsp; DriveNail(nailSupply &amp;#42;int, b &amp;#42;Board)&lt;br /&gt;
24 }&lt;br /&gt;
25&lt;br /&gt;
26 // NailPuller represents behavior to remove nails into a board.&lt;br /&gt;
27 type NailPuller interface {&lt;br /&gt;
28 &amp;nbsp; &amp;nbsp; PullNail(nailSupply &amp;#42;int, b &amp;#42;Board)&lt;br /&gt;
29 }&lt;br /&gt;
30&lt;br /&gt;
31 // NailDrivePuller represents behavior to drive/remove nails into a board.&lt;br /&gt;
32 type NailDrivePuller interface {&lt;br /&gt;
33 &amp;nbsp; &amp;nbsp; NailDriver&lt;br /&gt;
34 &amp;nbsp; &amp;nbsp; NailPuller&lt;br /&gt;
35 }
&lt;/div&gt;
&lt;br /&gt;
Listing 2 shows the interfaces that declare the behavior we need from the tools that may be used by the contractor. The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface on line 22 declares behavior to drive a single nail into a board. The method is given a supply of nails and the board to drive the nail into. The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface on line 27 declares the opposite behavior. The method is given a supply of nails and the board, but it will pull a nail from the board to place back into the supply.&lt;br /&gt;
&lt;br /&gt;
These two interfaces, &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt;, each implement a single, well defined behavior. This is what we want. Being able to break down behavior into individual, simple acts, lends itself to composability, flexibility and readability as you will see.&lt;br /&gt;
&lt;br /&gt;
The final interface declared on line 32 is named &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt;:
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 3&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
32 &amp;nbsp; &amp;nbsp; type NailDrivePuller interface {&lt;br /&gt;
33 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailDriver&lt;br /&gt;
34 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailPuller&lt;br /&gt;
35 &amp;nbsp; &amp;nbsp; }
&lt;/div&gt;
&lt;br /&gt;
This interface is composed from both the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interfaces. This is a very common pattern you will find in Go, taking existing interfaces and grouping them into composed behaviors. You will see how this plays into the code later on. For now, any concrete type value that implements both the driver and puller behaviors will also implement the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface.&lt;br /&gt;
&lt;br /&gt;
With the behaviors defined, it is time to declare and implement some tools:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 4&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
39 // Mallet is a tool that pounds in nails.&lt;br /&gt;
40 type Mallet struct{}&lt;br /&gt;
41&lt;br /&gt;
42 // DriveNail pounds a nail into the specified board.&lt;br /&gt;
43 func (Mallet) DriveNail(nailSupply &amp;#42;int, b &amp;#42;Board) {&lt;br /&gt;
44 &amp;nbsp; &amp;nbsp; // Take a nail out of the supply.&lt;br /&gt;
45 &amp;nbsp; &amp;nbsp; &amp;#42;nailSupply--&lt;br /&gt;
46&lt;br /&gt;
47 &amp;nbsp; &amp;nbsp; // Pound a nail into the board.&lt;br /&gt;
48 &amp;nbsp; &amp;nbsp; b.NailsDriven++&lt;br /&gt;
49&lt;br /&gt;
50 &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Mallet: pounded nail into the board.&amp;quot;)&lt;br /&gt;
51 }
&lt;/div&gt;
&lt;br /&gt;
In listing 4 on line 40, we have the declaration of a struct type named &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Mallet&lt;/span&gt;. This type is declared as an empty struct since there is no state that needs to be maintained. We only need to implement behavior.&lt;br /&gt;
&lt;br /&gt;
A mallet is a tool that is used to hammer in nails. So on line 43, the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface is implemented via the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;DriveNail&lt;/span&gt; method. The implementation of the method is irrelevant, it subtracts a value from the nail supply and adds a value to the board.&lt;br /&gt;
&lt;br /&gt;
Let’s look at the declaration and implementation of our second tool:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 5&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
53 // Crowbar is a tool that removes nails.&lt;br /&gt;
54 type Crowbar struct{}&lt;br /&gt;
55&lt;br /&gt;
56 // PullNail yanks a nail out of the specified board.&lt;br /&gt;
57 func (Crowbar) PullNail(nailSupply &amp;#42;int, b &amp;#42;Board) {&lt;br /&gt;
58 &amp;nbsp; &amp;nbsp; // Yank a nail out of the board.&lt;br /&gt;
59 &amp;nbsp; &amp;nbsp; b.NailsDriven--&lt;br /&gt;
60&lt;br /&gt;
61 &amp;nbsp; &amp;nbsp; // Put that nail back into the supply.&lt;br /&gt;
62 &amp;nbsp; &amp;nbsp; &amp;#42;nailSupply++&lt;br /&gt;
63&lt;br /&gt;
64 &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Crowbar: yanked nail out of the board.&amp;quot;)&lt;br /&gt;
65 }
&lt;/div&gt;
&lt;br /&gt;
In listing 5, we have the declaration of our second tool on line 54. This type represents a crowbar which can be used to pull nails from a board. On line 57, we have the implementation of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface via the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;PullNail&lt;/span&gt; method. The implementation once again is irrelevant but you can see how a nail is subtracted from the board and added to the nail supply.&lt;br /&gt;
&lt;br /&gt;
At this point in the code, we have declared tooling behavior via our interfaces and implemented that behavior via a set of struct types that represent two distinct tools our contractor can use. Now, let’s create a type that represents a contractor who performs the work using these tools:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 6&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
69 // Contractor carries out the task of securing boards.&lt;br /&gt;
70 type Contractor struct{}&lt;br /&gt;
71&lt;br /&gt;
72 // Fasten will drive nails into a board.&lt;br /&gt;
73 func (Contractor) Fasten(&lt;b&gt;d NailDriver&lt;/b&gt;, nailSupply &amp;#42;int, b &amp;#42;Board) {&lt;br /&gt;
74 &amp;nbsp; &amp;nbsp; for b.NailsDriven &amp;lt; b.NailsNeeded {&lt;br /&gt;
75 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;d.DriveNail(nailSupply, b)&lt;/b&gt;&lt;br /&gt;
76 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
77 }
&lt;/div&gt;
&lt;br /&gt;
In listing 6, we have the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Contractor&lt;/span&gt; type on line 70. Again, we don’t need any state so we are using an empty struct. Then on line 73, we see the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method, one of the three methods declared against the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Contractor&lt;/span&gt; type.&lt;br /&gt;
&lt;br /&gt;
The method &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; is declared to provide a contractor the behavior to drive the number of nails that are needed into a specified board. The method requires the user to pass as the first parameter a value that implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface. This value represents the tool the contractor will use to execute this behavior. Using an interface type for the this parameter allows the user of the API to later create and use different tools without the need for the API to change. The user is providing the behavior of the tooling and the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method is providing the workflow for when and how the tool is used.&lt;br /&gt;
&lt;br /&gt;
Notice we are using the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface and not the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface for the parameter’s type. This is very important since the only behavior that is needed by the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method is the ability to drive nails. By declaring only the behaviors we need, our code is easier to comprehend while also being easier to use due to minimal coupling. Now, let’s look at the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Unfasten&lt;/span&gt; method:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 7&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
79 // Unfasten will remove nails from a board.&lt;br /&gt;
80 func (Contractor) Unfasten(&lt;b&gt;p NailPuller&lt;/b&gt;, nailSupply &amp;#42;int, b &amp;#42;Board) {&lt;br /&gt;
81 &amp;nbsp; &amp;nbsp; for b.NailsDriven &amp;gt; b.NailsNeeded {&lt;br /&gt;
82 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;p.PullNail(nailSupply, b)&lt;/b&gt;&lt;br /&gt;
83 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
84 }
&lt;/div&gt;
&lt;br /&gt;
The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Unfasten&lt;/span&gt; method declared in listing 7 provides the contractor the opposite behavior of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method. This method will remove as many nails as necessary from the specified board and add those back into the supply. This method accepts only tools that implement the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface. This is exactly what we want since this is the only behavior required in the implementation of this method.&lt;br /&gt;
&lt;br /&gt;
The final behavior for a contractor is a method called &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; which allows the contractor to work on a set of boards at one time:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 8&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
86 // ProcessBoards works against boards.&lt;br /&gt;
87 func (c Contractor) ProcessBoards(&lt;b&gt;dp NailDrivePuller&lt;/b&gt;, nailSupply &amp;#42;int, boards []Board) {&lt;br /&gt;
88 &amp;nbsp; &amp;nbsp; for i := range boards {&lt;br /&gt;
89 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; b := &amp;amp;boards[i]&lt;br /&gt;
90&lt;br /&gt;
91 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;contractor: examining board #%d: %+v\n&amp;quot;, i+1, b)&lt;br /&gt;
92&lt;br /&gt;
93 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; switch {&lt;br /&gt;
94 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case b.NailsDriven &amp;lt; b.NailsNeeded:&lt;br /&gt;
95 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; c.Fasten(&lt;b&gt;dp&lt;/b&gt;, nailSupply, b)&lt;br /&gt;
96&lt;br /&gt;
97 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case b.NailsDriven &amp;gt; b.NailsNeeded:&lt;br /&gt;
98 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; c.Unfasten(&lt;b&gt;dp&lt;/b&gt;, nailSupply, b)&lt;br /&gt;
99 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
100 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
101 }
&lt;/div&gt;
&lt;br /&gt;
In listing 8, we see the declaration and implementation of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; method. This method accepts as its first parameter only values that implement both the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 9&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
87 func (c Contractor) ProcessBoards(&lt;b&gt;dp NailDrivePuller&lt;/b&gt;, nailSupply &amp;#42;int, boards []Board) {
&lt;/div&gt;
&lt;br /&gt;
Listing 9 shows how the method is declaring the exact behavior it needs via the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface type. We want our API’s to specify only the behaviors that are required or are being used. The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Unfasten&lt;/span&gt; methods require a value that implement a single act of behavior but &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; requires a value that implements two behaviors at the same time:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 10&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
93 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; switch {&lt;br /&gt;
94 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case b.NailsDriven &amp;lt; b.NailsNeeded:&lt;br /&gt;
95 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; c.Fasten(&lt;b&gt;dp&lt;/b&gt;, nailSupply, b)&lt;br /&gt;
96&lt;br /&gt;
97 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case b.NailsDriven &amp;gt; b.NailsNeeded:&lt;br /&gt;
98 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; c.Unfasten(&lt;b&gt;dp&lt;/b&gt;, nailSupply, b)&lt;br /&gt;
99 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;
&lt;br /&gt;
Listing 10 shows a piece of the implementation of &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; and how the value of interface type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; is used in the method calls to &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Unfasten&lt;/span&gt;. When the call to &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; is made on line 95, the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface value is passed into the method as an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt;. Let’s look at the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method once again:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 11&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
73 func (Contractor) Fasten(&lt;b&gt;d NailDriver&lt;/b&gt;, nailSupply &amp;#42;int, b &amp;#42;Board) {
&lt;/div&gt;
&lt;br /&gt;
Notice the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Fasten&lt;/span&gt; method requires a value of interface type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and we are passing a value of interface type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt;. This is possible because the compiler knows that any concrete type value that can be stored inside a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface value must also implement the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface. Therefore, the compiler accepts the method call and the assignment between these two interface type values.&lt;br /&gt;
&lt;br /&gt;
The same is true for the method call to &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Unfasten&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 12&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
80 func (Contractor) Unfasten(&lt;b&gt;p NailPuller&lt;/b&gt;, nailSupply &amp;#42;int, b &amp;#42;Board) 81 {
&lt;/div&gt;
&lt;br /&gt;
The compiler knows that any concrete type value that is stored inside an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriverPuller&lt;/span&gt; also implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface. Therefore, passing an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriverPuller&lt;/span&gt; is assignable to an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt;. Because there is a static relationship between these two interfaces, the compiler is able to forego generating a runtime type assertion and instead generate an interface conversion.&lt;br /&gt;
&lt;br /&gt;
With the contractor in place, we can now declare a new type that declares a toolbox for use by a contractor:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 13&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
105 // Toolbox can contains any number of tools.&lt;br /&gt;
106 type Toolbox struct {&lt;br /&gt;
107 &amp;nbsp; &amp;nbsp; NailDriver&lt;br /&gt;
108 &amp;nbsp; &amp;nbsp; NailPuller&lt;br /&gt;
109&lt;br /&gt;
110 &amp;nbsp; &amp;nbsp; nails int&lt;br /&gt;
111 }
&lt;/div&gt;
&lt;br /&gt;
Every good contractor has a toolbox and in listing 13 we have the declaration of a toolbox. The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; is a struct type that embeds on line 107 an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and on line 108 an interface value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt;. Then on line 110, a supply of nails is declared via the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;nails&lt;/span&gt; field.&lt;br /&gt;
&lt;br /&gt;
When embedding a type inside of another type, it is good to think of the new type as the outer type and the type being embedded as the inner type. This is important because then you can see the relationship that embedding a type creates.&lt;br /&gt;
&lt;br /&gt;
Any type that is embeded always exists as an inner value, inside the outer type value. It never loses its identity and is always there. However, thanks to inner type promotion, everything that is declared within the inner type is promoted to the outer type. This means through a value of the outer type, we can access any field or method associated with the inner type value directly based on the rules of exporting.&lt;br /&gt;
&lt;br /&gt;
Let’s look at an example of this:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 14&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
01 package main&lt;br /&gt;
02&lt;br /&gt;
03 import &amp;quot;fmt&amp;quot;&lt;br /&gt;
04 &lt;br /&gt;
05 // user defines a user in the program.&lt;br /&gt;
06 type user struct {&lt;br /&gt;
07 &amp;nbsp; &amp;nbsp; name &amp;nbsp;string&lt;br /&gt;
08 &amp;nbsp; &amp;nbsp; email string&lt;br /&gt;
09 }&lt;br /&gt;
10&lt;br /&gt;
11 // notify implements a method that can be called via&lt;br /&gt;
12 // a pointer of type user.&lt;br /&gt;
13 func (u &amp;#42;user) notify() {&lt;br /&gt;
14 &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Sending user email To %s&amp;lt;%s&amp;gt;\n&amp;quot;,&lt;br /&gt;
15 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; u.name,&lt;br /&gt;
16 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; u.email)&lt;br /&gt;
17 }
&lt;/div&gt;
&lt;br /&gt;
In listing 14, we have the declaration of a type named &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt;. This type contains two &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;string&lt;/span&gt; fields and a method named &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;notify&lt;/span&gt;. Now, let’s embed this type into another type:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 15&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
19 // admin represents an admin user with privileges.&lt;br /&gt;
20 type admin struct {&lt;br /&gt;
21 &amp;nbsp; &amp;nbsp; user &amp;nbsp;// Embedded Type&lt;br /&gt;
22 &amp;nbsp; &amp;nbsp; level string&lt;br /&gt;
23 }
&lt;/div&gt;
&lt;br /&gt;
Now we can see the relationship between the inner type and outer type in listing 15. The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt; type is now an inner type of &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt;, the outer type. This means that we can call the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;notify&lt;/span&gt; method directly from a value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; thanks to inner type promotion. But since the inner type value also exists, in and of itself, we can also call the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;notify&lt;/span&gt; method directly from the inner type value:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 16&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
25 // main is the entry point for the application.&lt;br /&gt;
26 func main() {&lt;br /&gt;
27 &amp;nbsp; &amp;nbsp; // Create an admin user.&lt;br /&gt;
28 &amp;nbsp; &amp;nbsp; ad := admin{&lt;br /&gt;
29 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user: user{&lt;br /&gt;
30 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name: &amp;nbsp;&amp;quot;john smith&amp;quot;,&lt;br /&gt;
31 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; email: &amp;quot;john@yahoo.com&amp;quot;,&lt;br /&gt;
32 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;
33 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; level: &amp;quot;super&amp;quot;,&lt;br /&gt;
34 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
35&lt;br /&gt;
36 &amp;nbsp; &amp;nbsp; // We can access the inner type's method directly.&lt;br /&gt;
37 &amp;nbsp; &amp;nbsp; ad.user.notify()&lt;br /&gt;
38&lt;br /&gt;
39 &amp;nbsp; &amp;nbsp; // The inner type's method is promoted to the outer type.&lt;br /&gt;
40 &amp;nbsp; &amp;nbsp; ad.notify()&lt;br /&gt;
41 }
&lt;/div&gt;
&lt;br /&gt;
Listing 16 shows how a value of the outer type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; is created using a struct literal on line 28. Inside the struct literal a second struct literal is used to create and initialize a value for the inner type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt;. With a value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; in place, we can call the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;notify&lt;/span&gt; method directly from the inner type value on line 37 or through the outer type value on line 40.&lt;br /&gt;
&lt;br /&gt;
One last thing, this is neither subtyping nor subclassing. Values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; can’t be used as values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt;. Values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; are only values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;admin&lt;/span&gt; and values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt; are only values of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;user&lt;/span&gt;. Thanks to inner type promotion, the fields and methods of the inner type can be accessed directly through a value of the outer type.&lt;br /&gt;
&lt;br /&gt;
Now back to our toolbox:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 17&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
105 // Toolbox can contains any number of tools.&lt;br /&gt;
106 type Toolbox struct {&lt;br /&gt;
107 &amp;nbsp; &amp;nbsp; NailDriver&lt;br /&gt;
108 &amp;nbsp; &amp;nbsp; NailPuller&lt;br /&gt;
109&lt;br /&gt;
110 &amp;nbsp; &amp;nbsp; nails int&lt;br /&gt;
111 }
&lt;/div&gt;
&lt;br /&gt;
We have not embedded a struct type into our &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; but two interface types. This means any concrete type value that implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; interface can be assigned as the inner type value for the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; embedded interface type. The same holds true for the embedded &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface type.&lt;br /&gt;
&lt;br /&gt;
Once a concrete type is assigned, the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; is then guaranteed to implement this behavior. Even more, since the toolbox embeds both a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface type, this means a &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; also implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface as well:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 18&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
31 &amp;nbsp; &amp;nbsp; NailDrivePuller interface {&lt;br /&gt;
32 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailDriver&lt;br /&gt;
33 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailPuller&lt;br /&gt;
34 &amp;nbsp; &amp;nbsp; }&lt;/div&gt;
&lt;br /&gt;
In listing 18 we see the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface again. Embedding interface types takes the idea of inner type promotion and interface compliance to the next level.&lt;br /&gt;
&lt;br /&gt;
Now we are ready to put everything together by implementing the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;main&lt;/span&gt; function:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 19&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
115 // main is the entry point for the application.&lt;br /&gt;
116 func main() {&lt;br /&gt;
117 &amp;nbsp; &amp;nbsp; // Inventory of old boards to remove, and the new boards&lt;br /&gt;
118 &amp;nbsp; &amp;nbsp; // that will replace them.&lt;br /&gt;
119 &amp;nbsp; &amp;nbsp; boards := []Board{&lt;br /&gt;
120 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Rotted boards to be removed.&lt;br /&gt;
121 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsDriven: 3},&lt;br /&gt;
122 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsDriven: 1},&lt;br /&gt;
123 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsDriven: 6},&lt;br /&gt;
124&lt;br /&gt;
125 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Fresh boards to be fastened.&lt;br /&gt;
126 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsNeeded: 6},&lt;br /&gt;
127 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsNeeded: 9},&lt;br /&gt;
128 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {NailsNeeded: 4},&lt;br /&gt;
129 &amp;nbsp; &amp;nbsp; }&lt;/div&gt;
&lt;br /&gt;
The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;main&lt;/span&gt; function starts out on line 116 in listing 19. Here we create a slice of boards and specify what each board needs in terms of nails. Next, we create our toolbox:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 20&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
131 &amp;nbsp; &amp;nbsp; // Fill a toolbox.&lt;br /&gt;
132 &amp;nbsp; &amp;nbsp; tb := Toolbox{&lt;br /&gt;
133 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailDriver: Mallet{},&lt;br /&gt;
134 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NailPuller: Crowbar{},&lt;br /&gt;
135 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nails: &amp;nbsp; &amp;nbsp; &amp;nbsp;10,&lt;br /&gt;
136 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
137&lt;br /&gt;
138 &amp;nbsp; &amp;nbsp; // Display the current state of our toolbox and boards.&lt;br /&gt;
139 &amp;nbsp; &amp;nbsp; displayState(&amp;amp;tb, boards)&lt;/div&gt;
&lt;br /&gt;
In listing 20, we create our &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; value and create a value of the struct type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Mallet&lt;/span&gt; and assign it to the inner interface type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt;. Then we create a value of struct type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Crowbar&lt;/span&gt; and assign it to the inner interface type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt;. Finally, we add 10 nails to the toolbox.&lt;br /&gt;
&lt;br /&gt;
Now let’s create the contractor and process some boards:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 21&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
141 &amp;nbsp; &amp;nbsp; // Hire a contractor and put our contractor to work.&lt;br /&gt;
142 &amp;nbsp; &amp;nbsp; var c Contractor&lt;br /&gt;
143 &amp;nbsp; &amp;nbsp; c.ProcessBoards(&lt;b&gt;&amp;amp;tb&lt;/b&gt;, &amp;amp;tb.nails, boards)&lt;br /&gt;
144&lt;br /&gt;
145 &amp;nbsp; &amp;nbsp; // Display the new state of our toolbox and boards.&lt;br /&gt;
146 &amp;nbsp; &amp;nbsp; displayState(&amp;amp;tb, boards)&lt;br /&gt;
147 }
&lt;/div&gt;
&lt;br /&gt;
On line 142 in listing 21 we create a value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Contractor&lt;/span&gt; and call the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoard&lt;/span&gt; method against it on line 143. Let’s look at the declaration of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; method once more:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 22&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
87 func (c Contractor) ProcessBoards(&lt;b&gt;dp NailDrivePuller&lt;/b&gt;, nailSupply &amp;#42;int, boards []Board) {
&lt;/div&gt;
&lt;br /&gt;
Once again, we see how the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoard&lt;/span&gt; method takes as its first parameter any concrete type value that implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface. Thanks to the type embedding of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDriver&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailPuller&lt;/span&gt; interface types inside the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; struct type, a pointer of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; implements the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;NailDrivePuller&lt;/span&gt; interface and can be passed through.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Note&lt;/b&gt;: The &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Mallet&lt;/span&gt; and &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Crowbar&lt;/span&gt; types implement their respective interfaces with value receivers. Based on the rules for &lt;a href="https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html" target="_blank"&gt;Method Sets&lt;/a&gt;, both values and pointers then satisfy the interface. This is why we can create and assign values of our concrete type values to the embedded interface type values. The call to &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;ProcessBoards&lt;/span&gt; in listing 21 on line 143 is using the address of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; value because we want to share a single &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt;. However, a value of type &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;Toolbox&lt;/span&gt; also satisfies the interface. If the concrete types used pointer receivers to implement the interfaces, then only pointers would have satisfied the interface.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
To be complete, here is the implementation of the &lt;span style="font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;"&gt;displayState&lt;/span&gt; function:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;&amp;nbsp; &lt;b&gt;Listing 23&lt;/b&gt; &amp;nbsp;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
149 // displayState provide information about all the boards.&lt;br /&gt;
150 func displayState(tb &amp;#42;Toolbox, boards []Board) {&lt;br /&gt;
151 &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Box: %#v\n&amp;quot;, tb)&lt;br /&gt;
152 &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Boards:&amp;quot;)&lt;br /&gt;
153&lt;br /&gt;
154 &amp;nbsp; &amp;nbsp; for _, b := range boards {&lt;br /&gt;
155 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;\t%+v\n&amp;quot;, b)&lt;br /&gt;
156 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
157&lt;br /&gt;
158 &amp;nbsp; &amp;nbsp; fmt.Println()&lt;br /&gt;
159 }
&lt;/div&gt;
&lt;br /&gt;
In conclusion, this example has tried to show how composition can be applied and the things to think about when writing your code. How you declare your types and how they can work together is very important. Here is a summary of the things we touch upon in the post:&lt;br /&gt;
&lt;br /&gt;
&amp;#42; Declare the set of behaviors as discrete interface types first. Then think about how they can be composed into a larger set of behaviors.&lt;br /&gt;
&lt;br /&gt;
&amp;#42; Make sure each function or method is very specific about the interface types they accept. Only accept interface types for the behavior you are using in that function or method. This will help dictate the larger interface types that are required.&lt;br /&gt;
&lt;br /&gt;
&amp;#42; Think about embedding as an inner and outer type relationship. Remember that through inner type promotion, everything that is declared in the inner type is promoted to the outer type. However, the inner type value exists in and of itself as is always accessible based on the rules for exporting.&lt;br /&gt;
&lt;br /&gt;
&amp;#42; Type embedding is not subtyping nor subclassing. Concrete type values represent a single type and can’t be assigned based on any embedded relationship.&lt;br /&gt;
&lt;br /&gt;
&amp;#42; The compiler can arrange interface conversions between related interface values.&amp;nbsp;Interface conversion, at compile time, doesn't care about concrete types - it knows what to do merely based on the interface types themselves, not the implementing concrete values they could contain.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;I would like to thank &lt;a href="https://twitter.com/kevingillette" target="_blank"&gt;Kevin Gillette&lt;/a&gt; for working with me on the code and post and &lt;a href="https://twitter.com/billhathaway" target="_blank"&gt;Bill Hathaway&lt;/a&gt;&amp;nbsp;for helping with reviews and edits to the post.&lt;/i&gt;</description></item><item><title>Object Oriented Programming Mechanics</title><link>https://www.ardanlabs.com/blog/2015/03/object-oriented-programming-mechanics.html</link><pubDate>Sun, 15 Mar 2015 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2015/03/object-oriented-programming-mechanics.html</guid><description>&lt;div class="p1"&gt;
Go is an object oriented programming language. It may not have inheritance, but in this 20 minute video from the Bangalore meetup, I will show you how object oriented programming practices and techniques can be applied to your Go programs. From an object oriented standpoint, Go does provides the ability to add behavior to your types via methods, allows you to implement polymorphic behavior via interfaces and gives you a way to extend the state and behavior of any existing type via type embedding. Go also provides a form of encapsulation that allows your types, including their fields and methods, to be visible or invisible. Everything you need to write object oriented programs is available in Go.&lt;/div&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="510" src="https://www.youtube.com/embed/gRpUfjTwSOo" width="100%"&gt;&lt;/iframe&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Example 1 - Methods: &lt;/b&gt;&lt;br /&gt;
&lt;a href="http://play.golang.org/p/hfRkC6nKag" target="_blank"&gt;http://play.golang.org/p/hfRkC6nKag&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Example 2 - Interfaces:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://play.golang.org/p/F1UyKlTh3k" target="_blank"&gt;http://play.golang.org/p/F1UyKlTh3k&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Example 3 - Extending Types:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://play.golang.org/p/JJ811lBwoz" target="_blank"&gt;http://play.golang.org/p/JJ811lBwoz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Example 4 - Overriding Inner Types:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://play.golang.org/p/-xQFBv9_82" target="_blank"&gt;http://play.golang.org/p/-xQFBv9_82&lt;/a&gt;</description></item><item><title>Scheduler Tracing In Go</title><link>https://www.ardanlabs.com/blog/2015/02/scheduler-tracing-in-go.html</link><pubDate>Mon, 23 Feb 2015 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2015/02/scheduler-tracing-in-go.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;
&lt;br /&gt;
One of the things I love about Go is the profiling and debug information you can generate. There is a special environmental variable named &lt;span style="font-family: Courier New, Courier, monospace;"&gt;GODEBUG&lt;/span&gt; that will emit debugging information about the runtime as your program executes. You can request summary and detailed information for both the garbage collector and the scheduler. What’s great is you don&amp;rsquo;t need to build your program with any special switches for it to work.&lt;/p&gt;</description></item><item><title>Stack Traces In Go</title><link>https://www.ardanlabs.com/blog/2015/01/stack-traces-in-go.html</link><pubDate>Sun, 11 Jan 2015 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2015/01/stack-traces-in-go.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
Having some basic skills in debugging Go programs can save any programmer a good amount of time trying to identify problems. I believe in logging as much information as you can, but sometimes a panic occurs and what you logged is not enough. Understanding the information in a stack trace can sometimes mean the difference between finding the bug now or needing to add more logging and waiting for it to happen again.&lt;/p&gt;</description></item><item><title>Using Pointers In Go</title><link>https://www.ardanlabs.com/blog/2014/12/using-pointers-in-go.html</link><pubDate>Tue, 16 Dec 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/12/using-pointers-in-go.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
I am asked quite a bit about when and when not to use pointers in Go. The problem most people have, is that they try to make this decision based on what they think the performance tradeoff will be. Hence the problem, don’t make coding decisions based on unfounded thoughts you may have about performance. Make coding decisions based on the code being idiomatic, simple, readable and reasonable.&lt;/p&gt;</description></item><item><title>Error Handling In Go, Part II</title><link>https://www.ardanlabs.com/blog/2014/11/error-handling-in-go-part-ii.html</link><pubDate>Mon, 10 Nov 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/11/error-handling-in-go-part-ii.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
In &lt;a href="https://www.ardanlabs.com/blog/2014/10/error-handling-in-go-part-i.html" target="_blank"&gt;part I&lt;/a&gt; of this post, we learned about the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;error&lt;/span&gt; interface and how the standard library provides support for creating &lt;span style="font-family: Courier New, Courier, monospace;"&gt;error&lt;/span&gt; interface values via the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;errors&lt;/span&gt; package. We also learned how to work with &lt;span style="font-family: Courier New, Courier, monospace;"&gt;error&lt;/span&gt; interface values and use them to identify when an error has occured. Finally, we saw how some packages in the standard library export &lt;span style="font-family: Courier New, Courier, monospace;"&gt;error&lt;/span&gt; interface variables to help us identify specific errors.&lt;/p&gt;</description></item><item><title>Error Handling In Go, Part I</title><link>https://www.ardanlabs.com/blog/2014/10/error-handling-in-go-part-i.html</link><pubDate>Mon, 13 Oct 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/10/error-handling-in-go-part-i.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
It is idiomatic in Go to use the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;error&lt;/span&gt; interface type as the return type for any error that is going to be returned from a function or method. This interface is used by all the functions and methods in the standard library that return errors. For example, here is the declaration for the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Get&lt;/span&gt; method from the &lt;span style="font-family: Courier New, Courier,
monospace;"&gt;http&lt;/span&gt; package:
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #eeeeee;"&gt;  &lt;b&gt;Listing 1.1&lt;/b&gt;  &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Go Compiler nil Pointer Checks</title><link>https://www.ardanlabs.com/blog/2014/09/go-compiler-nil-pointer-checks.html</link><pubDate>Mon, 01 Sep 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/09/go-compiler-nil-pointer-checks.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
I was thinking about how the compiler looks to protect the code we write when it can. Invalid memory access checks are one type of safety check the compiler adds to our code. We might think that this &amp;quot;extra code&amp;quot; is hurting our performance and maybe over billions of iterative operations it is. However, these checks can prevent our code from causing damage to the systems we are running on. The compiler is essentially reporting and finding bugs, making the code we write safer to run.&lt;br /&gt;
&lt;br /&gt;
Even with this in mind, Go wants to be fast and if the hardware can catch a problem, it will let it. One of these cases is with the detection of invalid memory access. There are times when the compiler will add a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;nil&lt;/span&gt; pointer check into our code and times when it doesn&amp;rsquo;t. In this post we will explore one case where the compiler leaves it up to the hardware to detect invalid memory access and one case where the compiler adds a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;nil&lt;/span&gt; pointer check.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Hardware Only Checks&lt;/span&gt;&lt;br /&gt;
When the compiler can depend on the hardware to check for and report invalid memory access, the compiler can produce less code which helps with performance. If our code attempts to read or write to address &lt;span style="font-family: Courier New, Courier, monospace;"&gt;0x0&lt;/span&gt;, the hardware will throw an exception that will be caught by the Go runtime and reported back up to our program in the form of a panic. If the panic is not recovered, a stack trace is produced.&lt;br /&gt;
&lt;br /&gt;
Here is an example that attempts to write to memory address &lt;span style="font-family: Courier New, Courier, monospace;"&gt;0x0 &lt;/span&gt;and the corresponding panic/stack trace:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>ALS Ice Bucket Challenge - Go Style</title><link>https://www.ardanlabs.com/blog/2014/08/als-ice-bucket-challenge-go-style.html</link><pubDate>Sat, 30 Aug 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/08/als-ice-bucket-challenge-go-style.html</guid><description>&lt;p&gt;If you have not heard about the &lt;a href="http://www.alsa.org/fight-als/ice-bucket-challenge.html" target="_blank"&gt;ALS Ice Bucket Challenge&lt;/a&gt; I would be surprised. It&amp;rsquo;s everywhere nowadays, being done by celebrities alike. After being challenged by my children there was only one person, or should I say Gopher, I knew I needed to nominate. The Gopher took to the challenge and here it is:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/FoEB4dI1Gas" width="640"&gt;&lt;/iframe&gt;
&lt;br /&gt;
I would like to thank my daughter for spending time today filming and editing the video. She is a senior member of the award winning&amp;nbsp;[ West Broward High School TV Production Club ](/broken-link). They&amp;nbsp;do amazing work so please give them a shot out on twitter at&amp;nbsp;&lt;a href="https://twitter.com/wbtvclub" target="_blank"&gt;@wbtvclub&lt;/a&gt;&amp;nbsp;if you enjoyed the video.&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;The Gopher character is based on the Go mascot designed by Renée French and copyrighted under the Creative Commons Attribution 3.0 license.&lt;/i&gt;</description></item><item><title>Ice Cream Makers and Data Races Part II</title><link>https://www.ardanlabs.com/blog/2014/06/ice-cream-makers-and-data-races-part-ii.html</link><pubDate>Fri, 27 Jun 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/06/ice-cream-makers-and-data-races-part-ii.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
Dave Cheney published a post called &lt;a href="http://dave.cheney.net/2014/06/27/ice-cream-makers-and-data-races" target="_blank"&gt;Ice Cream Makers and Data Races&lt;/a&gt;. The post showed an example of an interesting data race that can occur when using an interface typed variable to make a method call. If you have not read the post yet please do. Once you read the post you will discover that the problem lies with the fact that an interface value is implemented internally using a two word header and that the Go memory model states only writes to a single word are atomic.&lt;br /&gt;
&lt;br /&gt;
The program in the post shows a race condition that allows two goroutines to perform a read and write operation at the same time against an interface value. Not synchronizing this read and write allows the read to observe a partial write to the interface value. This allows the method implementation for the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Ben&lt;/span&gt; type to operate against a value of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Jerry&lt;/span&gt; type and visa versa.&lt;br /&gt;
&lt;br /&gt;
In Dave&amp;rsquo;s example, the layout of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Ben&lt;/span&gt; and &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Jerry&lt;/span&gt; structs were identical in memory, so they were in some sense compatible. Dave suggested the chaos that would occur if they had different memory representations. This is because each implementation of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Hello&lt;/span&gt; method assumes the code is operating against values of the receiver type. When this bug surfaces, this is no longer the case. To give you a visual view of this suggested chaos, I am going to change the declaration of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Jerry&lt;/span&gt; type in two different ways. Both changes will give you some better insight into the interworking of interface types and memory.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;First Code Change&lt;/span&gt;&lt;br /&gt;
Let&amp;rsquo;s review the code and see the first set of changes. My changes to the original code are in bold:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Actionable Data With MongoDB and Go</title><link>https://www.ardanlabs.com/blog/2014/06/actionable-data-with-mongodb-and-go.html</link><pubDate>Wed, 25 Jun 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/06/actionable-data-with-mongodb-and-go.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
If you are building any kind of application for a consumer based product, it is common to have large amounts of application data being generated about your users. Running reports is a traditional use of this data, but what if you could make this data actionable? What if you could adapt the user experience by aggregating and testing this data against rules that could dictate actions or special messaging?&lt;br /&gt;
&lt;br /&gt;
In this post I am going to show you a way that could be used to make your application data &amp;quot;actionable&amp;quot;. We are going to review a sample program written in Go that leverages MongoDB&amp;rsquo;s aggregation pipeline to execute rules that aggregate and test data. The rule the program defines and executes determines what messaging we want to show the user based on their current set of financial transactions in the system.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The Data&lt;/span&gt;&lt;br /&gt;
We have two collections of data we will be using which are being hosted in a public &lt;a href="https://www.ardanlabs.com/broken-link"&gt;MongoLab&lt;/a&gt; database. The first collection contains credit card transactions for users. This data represent application generated data:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Pitfalls With Closures In Go</title><link>https://www.ardanlabs.com/blog/2014/06/pitfalls-with-closures-in-go.html</link><pubDate>Fri, 20 Jun 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/06/pitfalls-with-closures-in-go.html</guid><description>&lt;p&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
Closures in Go are a very powerful construct but they can also be the cause of bugs if you don’t understand how they work. In this post I am going to pull a small piece of code from Chapter 2 from the &lt;a href="https://www.amazon.com/Go-Action-William-Kennedy/dp/1617291781" target="_blank"&gt;Go In Action&lt;/a&gt; book that discusses a pitfall you can run into when using closures. The full code example can be found in the &lt;a href="https://github.com/goinaction/code/tree/master/chapter2/sample" target="_blank"&gt;Github repository&lt;/a&gt; for the book. Chapter 2 discusses this code example in full detail.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The Closure Pitfall&lt;/span&gt;&lt;br /&gt;
First let’s look at the piece of code:
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Methods, Interfaces and Embedded Types in Go</title><link>https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html</link><pubDate>Sat, 03 May 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
My business partner Ed asked me what would happen if a struct and an embedded field both implemented the same interface. We asked ourselves two questions:&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;Would the compiler throw an error because we now had two implementations of the interface?&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;If the compiler accepted the type declaration, how does the compiler determine which implementation to use for interface calls?&lt;/li&gt;
&lt;/ul&gt;
We hacked out some code to answer the questions and then I dug into the specification. What we found was really interesting and we believed worth sharing with others who are also learning the language. Once we learned the mechanics behind methods, interfaces, and embedded types, the answers seemed obvious. To get started, let’s talk about what methods are in Go.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Methods&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Go has both functions and methods. In Go, a method is a function that is declared with a &lt;a href="http://golang.org/ref/spec#Method_declarations" target="_blank"&gt;receiver&lt;/a&gt;. A receiver is a value or a pointer of a &lt;a href="http://golang.org/ref/spec#Types" target="_blank"&gt;named&lt;/a&gt; or &lt;a href="http://golang.org/ref/spec#Struct_types" target="_blank"&gt;struct&lt;/a&gt; type. All the methods for a given type belong to the type’s method set.&lt;br /&gt;
&lt;br /&gt;
Let’s declare a struct type and a method for that type:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type User struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Name string&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Email string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (u User) Notify() error&lt;/div&gt;
&lt;br /&gt;
First we declare a struct type named &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; and then we declare a method named &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; with a receiver that accepts a value of type &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt;. To call the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method we need a value or pointer of type &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
// Value of type User can be used to call the method&lt;br /&gt;
// with a value receiver.&lt;br /&gt;
bill := User{&amp;quot;Bill&amp;quot;, &amp;quot;bill@email.com&amp;quot;}&lt;br /&gt;
bill.Notify()&lt;br /&gt;
&lt;br /&gt;
// Pointer of type User can also be used to call a method&lt;br /&gt;
// with a value receiver.&lt;br /&gt;
jill := &amp;amp;User{&amp;quot;Jill&amp;quot;, &amp;quot;jill@email.com&amp;quot;}&lt;br /&gt;
jill.Notify()&lt;/div&gt;
&lt;br /&gt;
In the case where we are using a pointer, Go &lt;a href="http://golang.org/ref/spec#Calls" target="_blank"&gt;adjusts&lt;/a&gt; and dereferences the pointer so the call can be made. Be aware that when the receiver is not a pointer, the method is operating against a copy of the receiver value.&lt;br /&gt;
&lt;br /&gt;
We can change the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method to use a pointer for the receiver:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func (u &amp;#42;User) Notify() error&lt;/div&gt;
&lt;br /&gt;
Once again, we can call the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method like we did before:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
// Value of type User can be used to call the method&lt;br /&gt;
// with a pointer receiver. &lt;br /&gt;
bill := User{&amp;quot;Bill&amp;quot;, &amp;quot;bill@email.com&amp;quot;}&lt;br /&gt;
bill.Notify()&lt;br /&gt;
&lt;br /&gt;
// Pointer of type User can be used to call the method&lt;br /&gt;
// with a pointer receiver.&lt;br /&gt;
jill := &amp;amp;User{&amp;quot;Jill&amp;quot;, &amp;quot;jill@email.com&amp;quot;}&lt;br /&gt;
jill.Notify()&lt;/div&gt;
&lt;br /&gt;
If you are unsure about when to use a value or a pointer for the receiver, the Go wiki has a great set of &lt;a href="https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Receiver_Type" target="_blank"&gt;rules&lt;/a&gt; that you can follow. The Go wiki also contains a paragraph about the conventions the community follows for &lt;a href="https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Receiver_Names" target="_blank"&gt;naming&lt;/a&gt; receivers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Interfaces&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://golang.org/doc/effective_go.html#interfaces" target="_blank"&gt;Interfaces&lt;/a&gt; in Go are special and provide an incredible amount of flexibility and abstraction for our programs. They are a way of specifying that values and pointers of a particular type can behave in a specific way. From a language perspective, an interface is a type that specifies a &lt;a href="http://golang.org/ref/spec#Method_sets" target="_blank"&gt;method set&lt;/a&gt; and all the methods for an &lt;a href="http://golang.org/ref/spec#Interface_types" target="_blank"&gt;interface type&lt;/a&gt; are considered to be the interface.&lt;br /&gt;
&lt;br /&gt;
Let’s declare an interface in Go:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type Notifier interface {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Notify() error&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Here we declare an interface called &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notifier&lt;/span&gt; with a single method called &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt;. It is a &lt;a href="http://golang.org/doc/effective_go.html#interface-names" target="_blank"&gt;convention&lt;/a&gt; in Go to name interfaces with an &lt;span style="font-family: Courier New, Courier, monospace;"&gt;-er&lt;/span&gt; suffix when the interface contains only one method. This is not a hard rule but something we should honor, especially when the interface and method name have the same signature and meaning.&lt;br /&gt;
&lt;br /&gt;
We can specify as many methods as we want for our interfaces. In the standard library you will be hard pressed to find many interfaces with more than two methods. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Implementing Interfaces&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Go is unique when it comes to how we implement the interfaces we want our types to support. Go does not require us to explicitly state that our types implement an interface. If every method that belongs to an interface’s method set is implemented by our type, then our type is said to implement the interface.&lt;br /&gt;
&lt;br /&gt;
Let’s continue with our example by creating a function that accepts any value or pointer of a type that implements the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notifier&lt;/span&gt; interface:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func SendNotification(notify Notifier) error {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return notify.Notify()&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function calls the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method that is implemented by the value or pointer that is passed into the function. This function can be used to execute the specific behavior for any value or pointer of a given type that implements the interface.&lt;br /&gt;
&lt;br /&gt;
Let’s implement the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method for our &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type and call the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function passing a value of type &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func (u &amp;#42;User) Notify() error {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; log.Printf(&amp;quot;User: Sending User Email To %s&amp;lt;%s&amp;gt;\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; u.Name,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; u.Email)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return nil&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; user := User{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: &amp;nbsp;&amp;quot;janet jones&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Email: &amp;quot;janet@email.com&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SendNotification(user)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Output:&lt;br /&gt;
cannot use user (type User) as type Notifier in function argument:
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; User does not implement Notifier (Notify method has pointer receiver)&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/VieiPRDGVu" target="_blank"&gt;http://play.golang.org/p/VieiPRDGVu&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Why does the compiler not consider our value to be of a type that implements the interface? The rules for determining interface compliance are based on the receiver for those methods and how the interface call is being made. Here are the rules in the spec for how the compiler determines if the value or pointer for our type &lt;a href="http://golang.org/ref/spec#Method_sets" target="_blank"&gt;implements&lt;/a&gt; the interface:&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;The method set of the corresponding pointer type &amp;#42;T is the set of all methods with receiver &amp;#42;T or T&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that if the interface variable we are using to call a particular interface method contains a pointer, then methods with receivers based on both values and pointers will satisfy the interface. This rule does not apply for our example because we are passing a value to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function.&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;The method set of any other type T consists of all methods with receiver type T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that if the interface variable we are using to call a particular interface method contains a value, then only methods with receivers based on values will satisfy the interface. This rule does not apply for our example because the receiver for the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method accepts a pointer.&lt;br /&gt;
&lt;br /&gt;
Since those are the only two rules in the spec for interface compliance, I have derived this rule that applies to our example:&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;The method set of the corresponding type T &lt;u&gt;&lt;b&gt;does not&lt;/b&gt;&lt;/u&gt; consists of any methods with receiver type &amp;#42;T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This is our case and why we are receiving the compiler error. The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method is using a pointer for the receiver and we are using a value to make the interface method call. To fix this we just need to pass the address of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; value to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; user := &amp;amp;User{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: &amp;nbsp;&amp;quot;janet jones&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Email: &amp;quot;janet@email.com&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SendNotification(user)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Output:&lt;br /&gt;
User: Sending User Email To janet jones&amp;lt;janet@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/3NNiS4dMrK" target="_blank"&gt;http://play.golang.org/p/3NNiS4dMrK&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Embedded Types&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://golang.org/ref/spec#Struct_types" target="_blank"&gt;Struct types&lt;/a&gt; have the ability to contain anonymous or embedded fields. This is also called embedding a type. When we embed a type into a struct, the name of the type acts as the field name for what is then an embedded field.&lt;br /&gt;
&lt;br /&gt;
Let’s declare a new type and embed our &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type into it:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type Admin struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Level string&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
We have declared a new type called &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; and embedded the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type within the struct declaration. This is not inheritance but composition. There is no relationship between the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; and the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type.&lt;br /&gt;
&lt;br /&gt;
Let’s change &lt;span style="font-family: Courier New, Courier, monospace;"&gt;main&lt;/span&gt; to create a value of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type and pass the address of this value to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; admin := &amp;amp;Admin{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User: User{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: &amp;nbsp;&amp;quot;john smith&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Email: &amp;quot;john@email.com&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Level: &amp;quot;super&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SendNotification(admin)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Output&lt;br /&gt;
User: Sending User Email To john smith&amp;lt;john@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/2jZMCGEfxW" target="_blank"&gt;http://play.golang.org/p/2jZMCGEfxW&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Sure enough, we are able to call the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function with a pointer of type &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt;. Thanks to composition, the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type now implements the interface through the promotion of the methods from the embedded &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type.&lt;br /&gt;
&lt;br /&gt;
If the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type now contains the fields and methods of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type, then where are they in relationship to the struct? &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;When we &lt;a href="http://golang.org/doc/effective_go.html#embedding" target="_blank"&gt;embed&lt;/a&gt; a type, the methods of that type become methods of the outer type, but when they are invoked, the receiver of the method is the inner type, not the outer one.&amp;quot; - Effective Go&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Since the name of the embedded type acts as the field name and the embedded type exists as an inner type, we can then make the following method call:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
admin.User.Notify()&lt;br /&gt;
&lt;br /&gt;
// Output&lt;br /&gt;
User: Sending User Email To john smith&amp;lt;john@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/_huNeKVmXS" target="_blank"&gt;http://play.golang.org/p/_huNeKVmXS&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here we are accessing the field and method set of the inner type through the use of the type’s name. However, these fields and methods are also promoted to the outer type:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
admin.Notify()&lt;br /&gt;
&lt;br /&gt;
// Output&lt;br /&gt;
User: Sending User Email To john smith&amp;lt;john@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/v4ro-KHiKJ" target="_blank"&gt;http://play.golang.org/p/v4ro-KHiKJ&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So calling the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method using the outer type, calls the implementation of the inner type’s method.&lt;br /&gt;
&lt;br /&gt;
These are the rules for inner type &lt;a href="http://golang.org/ref/spec#Method_sets" target="_blank"&gt;method set promotion&lt;/a&gt; in Go:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:&lt;/i&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;If S contains an anonymous field T, the method sets of S and &amp;#42;S both include promoted methods with receiver T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that when we embed a type, methods for the embedded type with receivers that use a value are promoted and available for calling by values and pointers of the outer type.&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;The method set of &amp;#42;S also includes promoted methods with receiver &amp;#42;T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that when we embed a type, methods for the embedded type with receivers that use a pointer are promoted and available for calling by pointers of the outer type.&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;If S contains an anonymous field &amp;#42;T, the method sets of S and &amp;#42;S both include promoted methods with receiver T or &amp;#42;T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that when we embed a pointer of the type, methods for the embedded type with receivers that use both values and pointers are promoted and available for calling by values and pointers of the outer type.&lt;br /&gt;
&lt;br /&gt;
Since those are the only three rules in the spec for method promotion, I have derived this rule for one other case:&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;&lt;i&gt;If S contains an anonymous field T, the method set of S &lt;u&gt;&lt;b&gt;does not&lt;/b&gt;&lt;/u&gt; include promoted methods with receiver &amp;#42;T.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
This rule is stating that when we embed a type, methods for the embedded type with receivers that use a pointer are not promoted for calling by values of the outer type. This is consistent with the rules for interface compliance that we stated above.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Answering The Questions&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Now we can finalize the sample program that will provide the answers for the two questions we asked in the beginning of the post. Let’s implement the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notifier&lt;/span&gt; interface for the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func (a &amp;#42;Admin) Notify() error {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; log.Printf(&amp;quot;Admin: Sending Admin Email To %s&amp;lt;%s&amp;gt;\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; a.Name,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; a.Email)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return nil&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The implementation of the interface by the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type displays a message on behalf of an admin. This will help us determine which implementation gets called when we use a pointer of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type to make the function call to &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Now let’s create a value of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type and pass the address of that value to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function and see what happens:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; admin := &amp;amp;Admin{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User: User{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: &amp;nbsp;&amp;quot;john smith&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Email: &amp;quot;john@email.com&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Level: &amp;quot;super&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SendNotification(admin)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Output&lt;br /&gt;
Admin: Sending Admin Email To john smith&amp;lt;john@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/NkDioPJs04" target="_blank"&gt;http://play.golang.org/p/NkDioPJs04&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
As expected, the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type’s implementation of the interface is called by the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendNotification&lt;/span&gt; function. So now what happens when we call the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Notify&lt;/span&gt; method using the outer type:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
admin.Notify()
&lt;br /&gt;
&lt;br /&gt;
// Output&lt;br /&gt;
Admin: Sending Admin Email To john smith&amp;lt;john@email.com&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://play.golang.org/p/RG50rxC0d7" target="_blank"&gt;http://play.golang.org/p/RG50rxC0d7&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
We get the output for the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Admin&lt;/span&gt; type’s implementation. The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;User&lt;/span&gt; type’s implementation is no longer promoted to the outer type:&lt;br /&gt;
&lt;br /&gt;
So now we have the knowledge we need to answer the questions:&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;Would the compiler throw an error because we now had two implementations of the interface?&lt;/li&gt;
&lt;/ul&gt;
No, because when we use an embedded type, the unqualified type’s name acts as the field name. This has the effect of fields and methods of the embedded type having a unique name as an inner type of the struct. So we can have an inner and outer implementation of the same interface with each implementation being unique and accessible.&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;If the compiler accepted the type declaration, how does the compiler determine which implementation to use for interface calls?&lt;/li&gt;
&lt;/ul&gt;
If the outer type contains an implementation that satisfies the interface, it will be used. Otherwise, thanks to method promotion, any inner type that implements the interface can be used through the outer type.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The way methods, interfaces, and embedded types work together is something that makes Go very unique. These features help us create powerful constructs to achieve the same ends as object oriented code without all the complexity. With the language features that we talked about in this post, we can build abstracted and scalable frameworks with a minimal amount of code and confusion.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
The more I learn about the details of the language and the compiler, the more I come to appreciate how &lt;a href="http://en.wikipedia.org/wiki/Orthogonality_(programming)" target="_blank"&gt;orthogonal&lt;/a&gt; the language is. Small features that work together and allow us to be creative and use the language in ways not even the language designers thought or dreamed about. I recommend to take the time to learn the language features so you can do more with less and be both creative and productive at the same time.&lt;/div&gt;</description></item><item><title>Introduction To Numeric Constants In Go</title><link>https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html</link><pubDate>Sun, 06 Apr 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
One of the more unique features of Go is how the language implements constants. The rules for &lt;a href="http://golang.org/ref/spec#Constants" target="_blank"&gt;constants&lt;/a&gt; in the language specification are unique to Go. They provide the flexibility Go needs at the compiler level to make the code we write readable and intuitive while still maintaining a type safe language.&lt;br /&gt;
&lt;br /&gt;
This post will attempt to build a foundation for what numeric constants are, how they behave in their simplest form and how best to talk about them. There are a lot of little nuances, terms and concepts that can trip us up. Because of this, the post is going to take things slowly.&lt;br /&gt;
&lt;br /&gt;
So if you are ready to peek under the covers just a bit, roll up your sleeve and let’s get started: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Untyped and Typed Numeric Constants&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Constants can be declared with or without a type in Go. When we declare literal values in our code, we are actually declaring constants that are both untyped and unnamed.&lt;br /&gt;
&lt;br /&gt;
The following examples show typed and untyped numeric constants that are both named and unnamed:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Exported/Unexported Identifiers In Go</title><link>https://www.ardanlabs.com/blog/2014/03/exportedunexported-identifiers-in-go.html</link><pubDate>Sat, 15 Mar 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/03/exportedunexported-identifiers-in-go.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
One of the first things I learned about in Go was using an uppercase or lowercase letter as the first letter when naming a type, variable or function. It was explained that when the first letter was capitalized, the identifier was public to any piece of code that wanted to use it. When the first letter was lowercase, the identifier was private and could only be accessed within the package it was declared.&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Web Form Validation And Localization In Go</title><link>https://www.ardanlabs.com/blog/2014/03/web-form-validation-and-localization-in.html</link><pubDate>Fri, 07 Mar 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/03/web-form-validation-and-localization-in.html</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
As I improve my knowledge and framework for a Go based web service I am building, I continue to go back and enhance my &lt;a href="https://www.ardanlabs.com/blog/2013/12/sample-web-application-using-beego-and.html" target="_blank"&gt;Beego Sample App&lt;/a&gt;. Something I just added recently was providing localized messages for validation errors. I was fortunate to find Nick Snyder's &lt;a href="https://github.com/nicksnyder/go-i18n" target="_blank"&gt;go-i18n&lt;/a&gt; package. Nick's package made it easy to support multiple languages for the Go web service I am writing.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Abstracting go-i18n&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The go-i18n package is simple to use and you can use it to read files or strings that contain all the messages you want to localize. It has some nice features including variable substitution and support for handling plurals for each individual locale. Nick has documentation for his package, so I am going to show you how I abstracted and integrated go-i18n into the Beego sample app.&lt;br /&gt;
&lt;br /&gt;
I decided I didn't want to use files to store the messages, but create raw string literal variables. The less I had to worry about managing external resources the better. With that being said, I built a simple package that abstracted the support I needed. Luckily go-i18n supports passing in a string that can contain the JSON document with the message data:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_messages.go"&gt;&lt;/script&gt;
I am just using simple messages right now, but as you can see, the variable En_US is defined and assigned a JSON document with the messages I need localized. The go-i18n package also lets you define messages like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_sample.go"&gt;&lt;/script&gt;
In this sample, the translation has one message for the singular case and one for the plural case. There is also support for using variable substitution thanks to template support.&lt;br /&gt;
&lt;br /&gt;
Here is the localize package that provides support for the web service:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_full.go"&gt;&lt;/script&gt;
The Init function creates the default locale for the application. Currently the Beego Sample App only supports English for the United States. Eventually, we can add cases for the other locales. Obviously this can all be done through configuration in the future.&lt;br /&gt;
&lt;br /&gt;
The Init function uses the LoadJSON function to load the go-i18n datastore with the internal messages for the default locale. Later on we can use the LoadJSON function again to load more JSON documents for the same or different locales.&lt;br /&gt;
&lt;br /&gt;
The Init function also uses the NewTranslation function to obtain a new i18n.TranslateFunc object for the default locale. This object is used to retrieve messages from the go-i18n datastore. If we have a scenario where the default locale is not valid, we can use the NewTranslation function at any time to obtain an object for the locale we need.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Beego Integration&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
To see how I integrated the go-i18n package into the sample app, we need to look at the controller:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_controller.go"&gt;&lt;/script&gt;
As discussed in my previous post about the Beego Sample App, we define a struct with tags that are used by the Beego validation module. I added support for defining the error to be returned when validation fails, by providing a new tag called error. In this case the error tag contains the id of the localized message we want to return. The ParseAndValidate function will handle the rest:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_parseval.go"&gt;&lt;/script&gt;
When the Beego validation module finds a problem, then the real work begins. The function uses reflection to find the error tag on any of the fields in the param struct. If an error tag is found, the id of the localized message is stored along with the field name. Then the function ranges over all the errors that the Beego validation module found and if an error tag existed for that field, we use the id to retrieve the localized message.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Testing&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
If we run the run_endpoint_test.sh shell script, which can be found in the zscripts folder, we can see the localized message returned in the last test:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/goinggo/9417459.js?file=localization_result.go"&gt;&lt;/script&gt;
The last test is designed to validate the localized message is returned.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The Beego framework has been great for developing my Go web service. It has the right amount of framework and modules, like the validation module, when you need it. The ability to bring in a package like go-i18n and integrate it so easily is another big win for Beego.&lt;br /&gt;
&lt;br /&gt;
If you are in need for localizing your Go application, take a look at go-i18n and see if it can work for you.</description></item><item><title>Running MongoDB Queries Concurrently With Go</title><link>https://www.ardanlabs.com/blog/2014/02/running-queries-concurrently-against.html</link><pubDate>Tue, 25 Feb 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/02/running-queries-concurrently-against.html</guid><description>&lt;p&gt;&lt;i&gt;If you are attending GopherCon 2014 or plan to watch the videos once they are released, this article will prepare you for the talk by Gustavo Niemeyer and Steve Francia. It provides a beginners view for using the Go mgo driver against a MongoDB database. &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
MongoDB supports many different programming languages thanks to a great set of &lt;a href="http://docs.mongodb.org/ecosystem/drivers/"&gt;drivers&lt;/a&gt;. One such driver is the MongoDB Go driver which is called &lt;a href="http://labix.org/mgo"&gt;mgo&lt;/a&gt;. This driver has been externally developed by &lt;a href="https://www.ardanlabs.com/broken-link"&gt;Gustavo Niemeyer&lt;/a&gt; from Canonical, and eventually
&lt;a href="https://www.ardanlabs.com/broken-link"&gt;Steve Francia&lt;/a&gt;, the head of the drivers team at MongoDB Inc, took notice and offered support. Both Gustavo and Steve will be talking at &lt;a href="http://gophercon.com/"&gt;GopherCon 2014&lt;/a&gt; in April about &amp;quot;&lt;a href="https://www.ardanlabs.com/broken-link"&gt;Painless Data Storage With MongoDB and Go&lt;/a&gt; &amp;quot;. The talk centers around the mgo driver and how MongoDB and Go really work well together to build highly scalable and concurrent software.&lt;span id="docs-internal-guid-42314786-69f7-a6d7-0263-6f34798f5ee5"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
MongoDB and Go let us build scalable software on many different operating systems and architectures, without the need to install any frameworks or runtime environments. Go programs are native binaries and the Go tooling is constantly improving to create binaries that run as fast as equivalent C programs. That wouldn&amp;rsquo;t mean anything if writing code in Go was complicated and as tedious as writing programs in C. This is where Go really shines because once you get up to speed, writing programs in Go is fast and fun.&lt;br /&gt;
&lt;br /&gt;
In this post I am going to show you how to write a Go program using the mgo driver to connect and run queries concurrently against a MongoDB database. I will break down the sample code and explain a few things that seem to be always be a bit confusing to those new to MongoDB and Go.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Sample Program&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The sample program connects to a public MongoDB database I have hosted with &lt;a href="https://www.ardanlabs.com/broken-link"&gt;MongoLab&lt;/a&gt;. If you have &lt;a href="https://www.ardanlabs.com/blog/2013/06/installing-go-gocode-gdb-and-liteide.html"&gt;Go&lt;/a&gt; and &lt;a href="https://www.ardanlabs.com/broken-link"&gt;Bazaar&lt;/a&gt; installed on your machine, you can run the program. The program launches ten goroutines that individually query all the records from the buoy_stations collection inside the goinggo database. The records are unmarshaled into native Go types and each goroutine logs the number of documents returned:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>The Nature Of Channels In Go</title><link>https://www.ardanlabs.com/blog/2014/02/the-nature-of-channels-in-go.html</link><pubDate>Mon, 17 Feb 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/02/the-nature-of-channels-in-go.html</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
In my last post called &lt;a href="https://www.ardanlabs.com/blog/2014/01/concurrency-goroutines-and-gomaxprocs.html" target="_blank"&gt;Concurrency, Goroutines and GOMAXPROCS&lt;/a&gt;, I set the stage for talking about channels. We discussed what concurrency was and how goroutines played a role. With that foundation in hand, we can now understand the nature of channels and how they can be used to synchronize goroutines to share resources in a safe, less error prone and fun way.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;What Are Channels&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Channels are type safe message queues that have the intelligence to control the behavior of any goroutine attempting to receive or send on it. A channel acts as a conduit between two goroutines and will synchronize the exchange of any resource that is passed through it. It is the channel's ability to control the goroutines interaction that creates the synchronization mechanism. When a channel is created with no capacity, it is called an unbuffered channel. In turn, a channel created with capacity is called a buffered channel.&lt;br /&gt;
&lt;br /&gt;
To understand what the synchronization behavior will be for any goroutine interacting with a channel, we need to know the type and state of the channel. The scenarios are a bit different depending on whether we are using an unbuffered or buffered channel, so let's talk about each one independently.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Unbuffered Channels&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Unbuffered channels have no capacity and therefore require both goroutines to be ready to make any exchange. When a goroutine attempts to send a resource to an unbuffered channel and there is no goroutine waiting to receive the resource, the channel will lock the sending goroutine and make it wait. When a goroutine attempts to receive from an unbuffered channel, and there is no goroutine waiting to send a resource, the channel will lock the receiving goroutine and make it wait.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2014-02-16+at+10.10.54+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2014-02-16+at+10.10.54+AM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Concurrency, Goroutines and GOMAXPROCS</title><link>https://www.ardanlabs.com/blog/2014/01/concurrency-goroutines-and-gomaxprocs.html</link><pubDate>Wed, 29 Jan 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/01/concurrency-goroutines-and-gomaxprocs.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
When new people join the &lt;a href="http://www.meetup.com/Go-Miami/" target="_blank"&gt;Go-Miami&lt;/a&gt; group they always write that they want to learn more about Go&amp;rsquo;s concurrency model. Concurrency seems to be the big buzz word around the language. It was for me when I first started hearing about Go. It was Rob Pike&amp;rsquo;s &lt;a href="http://www.youtube.com/watch?v=f6kdp27TYZs" target="_blank"&gt;Go Concurrency Patterns&lt;/a&gt; video that finally convinced me I needed to learn this language.&lt;br /&gt;
&lt;br /&gt;
To understand how Go makes writing concurrent programs easier and less prone to errors, we first need to understand what a concurrent program is and the problems that result from such programs. I will not be talking about CSP (Communicating Sequential Processes) in this post, which is the basis for Go&amp;rsquo;s implementation of channels. This post will focus on what a concurrent program is, the role that goroutines play and how the GOMAXPROCS environment variable and runtime function affects the behavior of the Go runtime and the programs we write.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Processes and Threads&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
When we run an application, like the browser I am using to write this post, a process is created by the operating system for the application. The job of the process is to act like a container for all the resources the application uses and maintains as it runs. These resources include things like a memory address space, handles to files, devices and threads.&lt;br /&gt;
&lt;br /&gt;
A thread is a path of execution that is scheduled by the operating system to execute the code we write in our functions against a processor. A process starts out with one thread, the main thread, and when that thread terminates the process terminates. This is because the main thread is the origin for the application. The main thread can then in turn launch more threads and those threads can launch even more threads.&lt;br /&gt;
&lt;br /&gt;
The operating system schedules a thread to run on an available processor regardless of which process the thread belongs to. Each operating system has its own algorithms that make these decisions and it is best for us to write concurrent programs that are not specific to one algorithm or the other. Plus these algorithms change with every new release of an operating system, so it is dangerous game to play.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Goroutines and Parallelism&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Any function or method in Go can be created as a goroutine. We can consider that the main function is executing as a goroutine, however the Go runtime does not start that goroutine. Goroutines are considered to be lightweight because they use little memory and resources plus their initial stack size is small. Prior to version 1.2 the stack size started at 4K and now as of version 1.4 it starts at 8K. The stack has the ability to grow as needed.&lt;br /&gt;
&lt;br /&gt;
The operating system schedules threads to run against available processors and
the Go runtime schedules goroutines to run within a &lt;a href="https://www.ardanlabs.com/blog/2015/02/scheduler-tracing-in-go.html" target="_blank"&gt;logical processor&lt;/a&gt; that is bound to a
single operating system thread. By default, the Go runtime allocates a single
logical processor to execute all the goroutines that are created for our program. Even with
this single logical processor and operating system thread, hundreds of thousands of goroutines can be
scheduled to run concurrently with amazing efficiency and performance. It is not recommended to add more that one logical processor, but if you want to run goroutines in parallel, Go provides the ability to add more via the GOMAXPROCS environment variable or runtime function.&lt;br /&gt;
&lt;br /&gt;
Concurrency is not Parallelism. Parallelism is when two or more threads are
executing code simultaneously against different processors. If you configure the
runtime to use more than one logical processor, the scheduler will distribute goroutines
between these logical processors which will result in goroutines running on different operating system threads.
However, to have true parallelism you need to run your program on a machine with
multiple physical processors. If not, then the goroutines will be running concurrently against
a single physical processor, even though the Go runtime is using multiple logical processors.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Concurrency Example&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Let&amp;rsquo;s build a small program that shows Go running goroutines concurrently. In this example we are running the code with one logical processor:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Decode JSON Documents In Go</title><link>https://www.ardanlabs.com/blog/2014/01/decode-json-documents-in-go.html</link><pubDate>Tue, 21 Jan 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/01/decode-json-documents-in-go.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
We are working on a project where we have to make calls into a web service. Many of the web calls return very large documents that contain many sub-documents. The worst part is, we usually only need a handful of the fields for any given document and those fields tend to be scattered all over the place.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here is a sample of a smaller document:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Be Selected To Attend GopherCon 2014</title><link>https://www.ardanlabs.com/blog/2014/01/gophercon-2014-scholarship-for-women.html</link><pubDate>Thu, 16 Jan 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/01/gophercon-2014-scholarship-for-women.html</guid><description>&lt;p&gt;Gopher Academy &lt;a href="http://blog.gopheracademy.com/scholarship-for-women" target="_blank"&gt;announced&lt;/a&gt; a great program today.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Today I&amp;rsquo;d like to announce the GopherCon Scholarship Program. It&amp;rsquo;s goal is to increase the visibility of women in the Go community through the most direct path I can imagine: sponsoring their attendance to GopherCon 2014.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
The program works by you purchasing one of these special tickets. There will be a selection/nomination process and those woman selected will be able to attend GopherCon thanks to you. It is designed to make GopherCon the most inclusive and welcoming place for all people to get together and learn about Go based technologies.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.outcast.io/" target="_blank"&gt;OutCast.io&lt;/a&gt; and &lt;a href="http://www.ardanstudios.com/" target="_blank"&gt;Ardan Studios&lt;/a&gt; recognizes the need to find ways to engage more women and girls to become technology creators. We have daughters that we would love to see have more opportunity. There is a great organization called &lt;a href="http://www.chicktech.org/" target="_blank"&gt;ChickTech&lt;/a&gt;. They are leading the way in creating local programs to get more women and girls involved in technology. ChickTech is dedicated to:&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
&amp;quot;&lt;i style="font-weight: bold;"&gt;retaining women in the technology workforce and increasing the number of women and girls pursuing technology-based careers.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;rsquo;re interested, ChickTech is always looking for local mentors and volunteers. They have a way for you to make a difference that fits your schedule and interests. This is a chance for you to give back to the woman and girls in your life, it just takes an email to get started.&lt;br /&gt;
&lt;br /&gt;
We really want to help and do something special. I will be speaking at &lt;a href="http://www.gophercon.com/" target="_blank"&gt;GopherCon 2014&lt;/a&gt; in Denver this April and speakers get their flight and hotel room for free. We wanted to give that to some deserving woman who is passionate about technology and otherwise would not be able to attend the conference.&lt;br /&gt;
&lt;br /&gt;
If you&amp;rsquo;re interested in receiving this free trip to GopherCon or want to nominate someone you know, write a post about yourself or that person and why you/they would like to attend GopherCon. You can also write a post about something cool you are doing with Go. Write your post in Google Docs and share it with me at &lt;a href="mailto:bill@thekennedyclan.net"&gt;bill@thekennedyclan.net&lt;/a&gt;. GoingGo.net will publish your post and we, with the GopherCon team, will select a winner on February 15th.﻿&lt;br /&gt;
&lt;br /&gt;
We hope to get a great response and are very excited that we can be involved in this great scholarship program. It is important to get more women and girls active in technology and this is a great way to start.&lt;/p&gt;</description></item><item><title>Go Package Management For 2014</title><link>https://www.ardanlabs.com/blog/2014/01/go-package-management-for-2014.html</link><pubDate>Thu, 16 Jan 2014 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2014/01/go-package-management-for-2014.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
In October 2013 I sent out a call to action to the Go community. I wanted to form a group of Gophers that would come together and help write a specification and build a working implementation of a package management tool. We are not there yet, but the group did accomplish a few things:&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;We started a mailing list called &lt;a href="https://groups.google.com/forum/#!forum/go-package-management" target="_blank"&gt;Go package management&lt;/a&gt; [go-pm] where people could discuss ideas and get feedback on existing and new tools.&lt;/li&gt;
&lt;li style="color: black;"&gt;We wrote a &lt;a href="https://docs.google.com/document/d/1k-3mwBqAdTIKGcilWZPuKSMy3DWtfNRFDs9o98lcwHY" target="_blank"&gt;goals document&lt;/a&gt; that outlined what we wanted to accomplish along with guidelines and help for package management tool authors.&lt;/li&gt;
&lt;li style="color: black;"&gt;We identified and categorized the existing set of tools that are available for use.&lt;/li&gt;
&lt;li style="color: black;"&gt;We developed a set of user stories that describe the different scenarios people were facing.&lt;/li&gt;
&lt;li style="color: black;"&gt;We started a list of packages that tool developers can use to test their tools against.&lt;/li&gt;
&lt;li style="color: black;"&gt;We helped some of the tool developers find and fix bugs.&lt;/li&gt;
&lt;/ul&gt;
Overall I think the last 3 months have been productive and I am pleased with the results.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Building Tools&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
I have come to appreciate that there isn't going to be a silver bullet or a one tool fits all solution. I believe a majority of the use-cases that have been defined in the &lt;a href="https://docs.google.com/document/d/1k-3mwBqAdTIKGcilWZPuKSMy3DWtfNRFDs9o98lcwHY" target="_blank"&gt;goals document&lt;/a&gt; can be solved and building tools to handle these use-cases is worth the time and effort. If you're thinking about building a tool, please consider these guidelines which are outlined in the goals document:
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Work with the Go language as defined in the Go 1 spec of March 28, 2012.&lt;/b&gt;&lt;br /&gt;
Don’t implement solutions that require feature changes or build tools that change the way Go works.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Provide backwards compatibility with go get and the convention of using VCS repositories in the import paths.&lt;/b&gt;&lt;br /&gt;
The existing set of programs, build processes and workflows can’t break. You must respect the existing environments and allow them to continue to function.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Prevent version skewing.&lt;/b&gt;&lt;br /&gt;
Don’t build into the solution the potential for version skewing to occur. Such as requiring semantic versioning in the import path urls. Imports should not need to be changed to access the latest or different versions of a package.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Work on all operating systems and architectures that Go currently supports.&lt;/b&gt;&lt;br /&gt;
One of the great things about Go is that programs can be built on all these different operating systems and architectures. Your tool should not exclude a platform or make use of a specific operating system construct like symlinks.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Interoperate in such a way that ‘go get’ continues to work for package authors who do not wish to participate, or for existing Go source code that cannot be changed. Also, do not force package authors to choose between making their code go getable or using the proposed solution.&lt;/b&gt;&lt;br /&gt;
No one should be required to use a tool in order to share or import a repository. The tooling must continue to work for everyone.&lt;br /&gt;
&lt;br /&gt;
All these guidelines are important because they will allow others to try and use your tools without the need to refactor any existing code. They also guarantee that existing projects continue to build and install with the Go tooling on all platforms.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Choices&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
I would love to see the community rally around a few tools and help improve them. There are two classes of tools that I think work well with Go, Vendoring and Revision Locking.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Vendoring&lt;/b&gt; takes the 3rd party source code that is referenced in your project and makes a copy of that code inside a new folder within the project. All the code your project needs is inside the one project repository. Vendoring also provides a performance enhancement on getting the code because only one url call is required.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Revision Locking&lt;/b&gt; creates a dependency file that references specific commits in the different version control systems the code is located in. Just like vendoring, the RL tool is used to get, build and install your project. One advantage is that your project repository continues to only contain the specific project code.&lt;br /&gt;
&lt;br /&gt;
Choosing how to handle package management it is a matter of personal preference. The Go team recommends vendoring, which can be found in the Go &lt;a href="http://golang.org/doc/faq#get_version" target="_blank"&gt;FAQ&lt;/a&gt;. They mention Keith Rarick's tool &lt;a href="https://github.com/kr/goven" target="_blank"&gt;goven&lt;/a&gt; as an option. Keith has abandoned&amp;#42;&amp;#42; goven for his other tool &lt;a href="https://github.com/kr/godep" target="_blank"&gt;godep&lt;/a&gt;, which provides both vendoring and revision locking.
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;#42;&amp;#42; After talking with Keith he has stated that he has not totally abandoned goven, it is just &amp;quot;finished&amp;quot;. He continues to maintain the package and merge bug fixes when necessary.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;New Call To Action&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
For 2014 I would like to see the Go community play a greater role in helping the package management tool authors. There are several ways I think this can be done:
&lt;br /&gt;
&lt;ul&gt;
&lt;li style="color: black;"&gt;Participate in the &lt;a href="https://groups.google.com/forum/#!forum/go-package-management" target="_blank"&gt;go-pm group&lt;/a&gt;. Give advice and help to those who have questions.&lt;/li&gt;
&lt;li style="color: black;"&gt;Submit packages that the tool authors can use to help test their tools.&lt;/li&gt;
&lt;li style="color: black;"&gt;Report bugs and feature requests.&lt;/li&gt;
&lt;li style="color: black;"&gt;Continue to add user stories that are missing in the goals document.&lt;/li&gt;
&lt;li style="color: black;"&gt;Submit your new tools and ideas to the go-pm group.&lt;/li&gt;
&lt;li style="color: black;"&gt;Work with the existing tool authors to improve the tools that we have today.&lt;/li&gt;
&lt;/ul&gt;
I hope to see all of you participating in the go-pm mailing list this year. I love Go and only want to see it improve for everyone.</description></item><item><title>Macro View of Map Internals In Go</title><link>https://www.ardanlabs.com/blog/2013/12/macro-view-of-map-internals-in-go.html</link><pubDate>Tue, 31 Dec 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/12/macro-view-of-map-internals-in-go.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
There are lots of posts that talk about the internals of slices, but when it comes to maps, we are left in the dark. I was wondering why and then I found the code for maps and it all made sense.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.ardanlabs.com/broken-link"&gt;https://golang.org/src/runtime/hashmap.go&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
At least for me, this code is complicated. That being said, I think we can create a macro view of how maps are structured and grow. This should explain why they are unordered, efficient and fast.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Creating and Using Maps&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Let&amp;rsquo;s look at how we can use a map literal to create a map and store a few values:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Queue Your Way To Scalability</title><link>https://www.ardanlabs.com/blog/2013/12/queue-your-way-to-scalability.html</link><pubDate>Fri, 20 Dec 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/12/queue-your-way-to-scalability.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The first thing I did when I started programming in Go was begin porting my Windows utilities classes and service frameworks over to Linux. This is what I did when I moved from C++ to C#. Thank goodness, I soon learned about &lt;a href="http://www.iron.io/" target="_blank"&gt;Iron.IO&lt;/a&gt; and the services they offered. Then it hit me, if I wanted true scalability, I needed to start building worker tasks that could be queued to run anywhere at any time. It was not about how many machines I needed, it was about how much compute time I needed.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Three-Index Slices in Go 1.2</title><link>https://www.ardanlabs.com/blog/2013/12/three-index-slices-in-go-12.html</link><pubDate>Tue, 17 Dec 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/12/three-index-slices-in-go-12.html</guid><description>&lt;p&gt;With the release of Go 1.2, slices gained the ability to specify the capacity when performing a slicing operation. This doesn&amp;rsquo;t mean we can use this index to extend the capacity of the underlying array. It means we can create a new slice whose capacity is restricted. Restricting the capacity provides a level of protection to the underlying array and gives us more control over append operations.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here are the release notes and design document for the feature request:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://tip.golang.org/doc/go1.2#three_index" target="_blank"&gt;&lt;a href="http://tip.golang.org/doc/go1.2#three_index"&gt;http://tip.golang.org/doc/go1.2#three_index&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://docs.google.com/document/d/1GKKdiGYAghXRxC2BFrSEbHBZZgAGKQ-yXK-hRKBo0Kk/pub" target="_blank"&gt;&lt;a href="https://docs.google.com/document/d/1GKKdiGYAghXRxC2BFrSEbHBZZgAGKQ-yXK-hRKBo0Kk/pub"&gt;https://docs.google.com/document/d/1GKKdiGYAghXRxC2BFrSEbHBZZgAGKQ-yXK-hRKBo0Kk/pub&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Let&amp;rsquo;s write some code to explore using the new capacity index. As with all my slice posts, I am going to use this InspectSlice function:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Sample Web Application Using Beego and Mgo</title><link>https://www.ardanlabs.com/blog/2013/12/sample-web-application-using-beego-and.html</link><pubDate>Wed, 11 Dec 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/12/sample-web-application-using-beego-and.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
I am very excited about the Beego web framework. I wanted to share with you how I use the framework to build real world web sites and web services. Here is a picture of the sample website the post is going to showcase:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2014-02-08+at+5.37.01+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2014-02-08+at+5.37.01+PM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
The sample web application:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Implements a traditional grid view of data calling into MongoDB&lt;/li&gt;
&lt;li&gt;Provides a modal dialog box to view details using a partial view to generate the HTML&lt;/li&gt;
&lt;li&gt;Implements a web service that returns a JSON document&lt;/li&gt;
&lt;li&gt;Takes configuration parameters from the environment using &lt;a href="https://github.com/kelseyhightower/envconfig" target="_blank"&gt;envconfig&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Implements tests via &lt;a href="http://smartystreets.github.io/goconvey/" target="_blank"&gt;goconvey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Leverages my &lt;a href="https://github.com/goinggo/tracelog" target="_blank"&gt;logging&lt;/a&gt; package&lt;/li&gt;
&lt;/ol&gt;
The code for the sample can be found in the GoingGo repository up on Github:&lt;br /&gt;
&lt;a href="https://github.com/goinggo/beego-mgo" target="_blank"&gt;https://github.com/goinggo/beego-mgo&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You can bring the code down and run it. It uses a public MongoDB database I created at MongoLab. You will need &lt;a href="https://help.github.com/articles/set-up-git" target="_blank"&gt;git&lt;/a&gt; and &lt;a href="http://bazaar.canonical.com/en/" target="_blank"&gt;bazaar&lt;/a&gt; installed on your system before running go get.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
go get github.com/goinggo/beego-mgo&lt;/div&gt;
&lt;br /&gt;
To quickly run or test the web application, use the scripts located in the zscripts folder.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Web Application Code Structure&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Let's take a look at the project structure and the different folders that exist:
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
	&lt;table class="table table-bordered table-striped"&gt;
		&lt;tbody&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;controllers&lt;/td&gt;
				&lt;td&gt;Entry point for each Web call. Controllers process the requests.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;localize&lt;/td&gt;
				&lt;td&gt;Provides localization support for different languages and cultures&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;models&lt;/td&gt;
				&lt;td&gt;Models are data structures used by the business and service layers&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;routes&lt;/td&gt;
				&lt;td&gt;Mappings between URL's and the controller code that handles those calls.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;services&lt;/td&gt;
				&lt;td&gt;Services provide primitive functions for the different services that exist. These could be database or web calls that perform a specific function.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;static&lt;/td&gt;
				&lt;td&gt;Resource files such as scripts, stylesheets and images&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;test&lt;/td&gt;
				&lt;td&gt;Tests that can be run through the go test tool.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;utilities&lt;/td&gt;
				&lt;td&gt;Code that supports the web application. Boilerplate and abstraction layers for accessing the database and handling panics.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;views&lt;/td&gt;
				&lt;td&gt;Code related to rendering views&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td valign="top"&gt;zscripts&lt;/td&gt;
				&lt;td&gt;Support scripts to help make it easier to build, run and test the web application&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/tbody&gt;
	&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Controllers, Models and Services&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
These layers make up the bulk of the code that implement the web application. The idea behind the framework is to hide and abstract as much boilerplate code as possible. This is accomplished by implementing a base controller package and a base services package.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;Base Controller Package&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The base controller package uses composition to abstract default controller behavior required by all controllers:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; BaseController struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; beego.Controller&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; services.Service&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func (this &amp;#42;BaseController) Prepare() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.UserId = this.GetString(&amp;quot;userId&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if this.UserId == &amp;quot;&amp;quot; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.UserId = this.GetString(&amp;quot;:userId&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; err := this.Service.Prepare()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.ServeError(err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (this &amp;#42;BaseController) Finish() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if this.MongoSession != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mongo.CloseSession(this.UserId, this.MongoSession)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.MongoSession = nil&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }()&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
A new type called BaseController is declared with the Beego Controller type and the base Service type embedded directly. This composes the fields and methods of these types directly into the BaseController type and makes them directly accessible through an object of the BaseController type.&lt;br /&gt;
&lt;br /&gt;
Beego Controller framework will execute the Prepare and Finish functions on any Controller object that implements these interfaces. The Prepare function is executed prior to the Controller function being called. These functions will belong to every Controller type&amp;nbsp;by default, allowing this boilerplate code to be implemented once.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;Services Package&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The Service package maintains state and implements boilerplate code required by all services:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Services contains common properties&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Service struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MongoSession &amp;#42;mgo.Session&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; UserId string&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func (this &amp;#42;Service) Prepare() (err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.MongoSession, err = mongo.CopyMonotonicSession(this.UserId)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return err&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (this &amp;#42;Service) Finish() (err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer helper.CatchPanic(&amp;amp;err, this.UserId, &amp;quot;Service.Finish&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if this.MongoSession != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mongo.CloseSession(this.UserId, this.MongoSession)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.MongoSession = nil&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return err&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (this &amp;#42;Service) DBAction(databaseName string, collectionName string, mongoCall mongo.MongoCall) (err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return mongo.Execute(this.UserId, this.MongoSession, databaseName, collectionName, mongoCall)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
In the Service type, the Mongo session and the id of the user is maintained.&amp;nbsp;This version of Prepare handles creating a MongoDB session for use. Finish closes the session which releases the underlying connection back into the pool.&amp;nbsp;&amp;nbsp;The function DBAction provides an abstraction layer for running MongoDB commands and queries.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;Buoy Service&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
This Buoy Service package implements the calls to MongoDB. Let's look at the FindStation function that is called by the controller methods:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func FindStation(service &amp;#42;services.Service, stationId string) (buoyStation &amp;#42;buoyModels.BuoyStation, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer helper.CatchPanic(&amp;amp;err, service.UserId, &amp;quot;FindStation&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; queryMap := bson.M{&amp;quot;station_id&amp;quot;: stationId}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; buoyStation = &amp;amp;buoyModels.BuoyStation{}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; err = service.DBAction(Config.Database, &amp;quot;buoy_stations&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; func(collection &amp;#42;mgo.Collection) error {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return collection.Find(queryMap).One(buoyStation)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; })&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if strings.Contains(err.Error(), &amp;quot;not found&amp;quot;) == false {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return buoyStation, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = nil&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return buoyStation, err&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The FindStation function prepares the query and then using the DBAction function to execute the query against MongoDB.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Implementing Web Calls&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
With the base types, boilerplate code and service functionality in place, we can now implement the web calls.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;Buoy Controller&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The BuoyController type is composed solely from the BaseController. By composing the BuoyController in this way, it immediately satisfies the Prepare and Finish interfaces and contains all the fields of a Beego Controller.&lt;br /&gt;
&lt;br /&gt;
The controller functions are bound to routes. The routes specify the urls to the different web calls that the application supports. In our sample application we have three routes:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
beego.Router(&amp;quot;/&amp;quot;, &amp;amp;controllers.BuoyController{}, &amp;quot;get:Index&amp;quot;)&lt;br /&gt;
beego.Router(&amp;quot;/buoy/retrievestation&amp;quot;, &amp;amp;controllers.BuoyController{}, &amp;quot;post:RetrieveStation&amp;quot;)&lt;br /&gt;
beego.Router(&amp;quot;/buoy/station/:stationId&amp;quot;, &amp;amp;controllers.BuoyController{}, &amp;quot;get,post:RetrieveStationJson&amp;quot;)&lt;/div&gt;
&lt;br /&gt;
The route specifies a url path, an instance of the controller used to handle the call and the name of the method from the controller to use. A prefix of which verb is accepted can be specified as well.&lt;br /&gt;
&lt;br /&gt;
The Index controller method is used to deliver the initial html to the browser. This will include the javascript, style sheets and anything else needed to get the web application going:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func (this &amp;#42;BuoyController) Index() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; region := &amp;quot;Gulf Of Mexico&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; buoyStations, err := buoyService.FindRegion(&amp;amp;this.Service, region)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this.ServeError(err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.Data[&amp;quot;Stations&amp;quot;] = buoyStations&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.Layout = &amp;quot;shared/basic-layout.html&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.TplNames = &amp;quot;buoy/content.html&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.LayoutSections = map[string]string{}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.LayoutSections[&amp;quot;PageHead&amp;quot;] = &amp;quot;buoy/page-head.html&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.LayoutSections[&amp;quot;Header&amp;quot;] = &amp;quot;shared/header.html&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; this.LayoutSections[&amp;quot;Modal&amp;quot;] = &amp;quot;shared/modal.html&amp;quot;&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
A call is made into the service layer to retrieve the list of regions. Then the slice of stations are passed into the view system. Since this is setting up the initial view of the application, layouts and the template are specified. When the controller method returns, the beego framework will generate the html for the response and deliver it to the browser.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2014-02-08+at+4.36.44+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2014-02-08+at+4.36.44+PM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Building A Weather App Using Go</title><link>https://www.ardanlabs.com/blog/2013/12/building-weather-app-using-go.html</link><pubDate>Tue, 10 Dec 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/12/building-weather-app-using-go.html</guid><description>&lt;p&gt;&lt;a href="../../../images/goinggo/weather-main.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/weather-main.jpg" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At &lt;a href="http://www.ardanstudios.com/" target="_blank"&gt;Ardan Studios&lt;/a&gt; we have spent the last 6 months, in our spare time and on weekends, building a consumer based mobile application called &lt;a href="http://www.outcast.io/" target="_blank"&gt;OutCast&lt;/a&gt;. The mobile application is tailored towards those who like spending time outdoors, whether that be fishing, hunting or any other type of activity.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/buoys.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/buoys.jpg" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This first release of OutCast shows the conditions for the buoy stations and marine forecasts areas within the United States. All this information is updated every 10 minutes and there are map views with traditional grids and search.&lt;br /&gt;
&lt;br /&gt;
The backend processing for buoy and marine data is built using Go and running at &lt;a href="http://www.iron.io/" target="_blank"&gt;Iron.IO&lt;/a&gt; as a scheduled worker task. The buoy processing downloads a text file from the NOAA website and rips through it, updating MongoDB with any changes. The marine processing is a bit more complicated. This requires pulling down multiple web pages from the NOAA website and parsing out all the text. Go made building and running these tasks a breeze.&lt;br /&gt;
&lt;br /&gt;
Another important aspect of OutCast is real time weather radar for the last 50 minutes. This has been very challenging on multiple levels. Mainly because we needed a real good image library that would run on Linux and could be integrated with Go. We were fortunate to find ImageMagick&amp;rsquo;s MagickWand C API and their Go package that provides the CGO bindings (&lt;a href="https://github.com/gographics/imagick" target="_blank"&gt;&lt;a href="https://github.com/gographics/imagick"&gt;https://github.com/gographics/imagick&lt;/a&gt;&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Processing images is an intense piece of work. Sometimes it takes 3 seconds to clean a single image. With 155 radar stations
that need to be processed every 5 minutes, it took us several refactors to get things working well. The MagickWand library can
only handle processing one image at a time. This restriction places a lot of stress on getting things done accurately within
an acceptable amount of time.&lt;br /&gt;
&lt;br /&gt;
Here is a sample of a radar image before and after processing: &lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Write Your Go Programs Using GEdit</title><link>https://www.ardanlabs.com/blog/2013/11/write-your-go-programs-using-gedit.html</link><pubDate>Sat, 23 Nov 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/11/write-your-go-programs-using-gedit.html</guid><description>&lt;p&gt;&lt;i&gt;&lt;b&gt;This is a guest post from Tad Vizbaras from &lt;a href="http://www.etasoft.com/" target="_blank"&gt;Etasoft&lt;/a&gt; in South Florida.&lt;/b&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;br /&gt;
There are a number of editors and IDEs for Go development. LiteIde, Vim, Emacs and GEdit just to name a few. Each developer has their own favorite editor for each language they work with. Some like full featured IDE environments while others prefer speed over features. My personal favorite editors for Go development at the moment are Vim and GEdit.&lt;br /&gt;
&lt;br /&gt;
GEdit comes as part of many Linux distros. If you use Ubuntu, it is part of the operating system. GEdit has some decent features like:&lt;br /&gt;
&lt;br /&gt;
* Syntax Highlighting&lt;br /&gt;
* Split Windows&lt;br /&gt;
* Word Wrapping&lt;br /&gt;
&lt;br /&gt;
Advanced features are left to be handled by external plug-ins.&lt;br /&gt;
&lt;br /&gt;
I prefer project-less development. That means there are no formal project files and projects are preserved via a workspace bound to a directory structure. Go has excellent support for project-less development. When building and installing your projects, the Go tooling, in conjunction with the way Go packages code, can minimize the need for external scripts and makefiles.&lt;br /&gt;
&lt;br /&gt;
GEdit is a decent editor but I could not find any good Plug-ins that would allow me to perform a Go build right from the editor. The &amp;quot;External Tools&amp;quot; Plug-in has worked for me. I was able to set up shortcuts and get &amp;quot;go build&amp;quot; to execute. When you click on errors, displayed in the bottom pane of GEdit, the cursor jumps to exact error location.&lt;br /&gt;
&lt;br /&gt;
When I started programming in Go, the &amp;quot;External Tools&amp;quot; Plug-in worked for me for quite some time. But after awhile, I started to wish that &amp;quot;go build&amp;quot; would run similar to how Linters ran. With Linters, you can run a command after the file is saved. Since Go usually takes only few seconds to build, the Plug-in could execute a &amp;quot;go build&amp;quot; on save and then jump to the error location if there were any.&lt;br /&gt;
&lt;br /&gt;
I wrote a GEdit Plug-in that is developed in Python. Depending on the version of Python you have installed, you may require some small adjustments. This is covered in the Known Issues section below.&lt;br /&gt;
&lt;br /&gt;
Ops, I forgot to mention&amp;hellip; Go is Awesome. But you probably already know that.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Meet GoBuild for GEdit 3.x&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
GoBuild - GEdit 3 Plug-in for Go (golang) development.&lt;br /&gt;
&lt;br /&gt;
GoBuild Plug-in version 1.0 for GEdit. Plug-in attaches to the &lt;b&gt;on_save&lt;/b&gt; event in GEdit for Go source code files only. It does nothing for any other file type.&lt;br /&gt;
&lt;br /&gt;
It will run &amp;quot;go build&amp;quot; after the file is saved. If the current filename has &amp;quot;_test.go&amp;quot; in the name, then the Plug-in will run &amp;quot;go test&amp;quot; against the current file&amp;rsquo;s directory. The Plug-in will wait a number of seconds for the build or test to complete. It will timeout and quit the build or test so GEdit will not freeze.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Images&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Plug-in captures &amp;quot;go build&amp;quot; errors and shows them in the Gedit status bar. It also jumps to the first error and highlights error line if error is in the current file.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Label Breaks In Go</title><link>https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html</link><pubDate>Thu, 21 Nov 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html</guid><description>&lt;p&gt;Have you ever found yourself in this situation. You have a case statement inside of a for loop and you would like to break from both the case and for statements in a single call?&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
var err error&lt;br /&gt;
timeout := time.After(30 &amp;#42; time.Second)&lt;br /&gt;
&lt;br /&gt;
sigChan := make(chan os.Signal, 1)&lt;br /&gt;
signal.Notify(sigChan, os.Interrupt)&lt;br /&gt;
&lt;br /&gt;
complete := make(chan error)&lt;br /&gt;
go launchProcessor(complete)&lt;br /&gt;
&lt;br /&gt;
for {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; select {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; case &amp;lt;-sigChan:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;atomic.StoreInt32(&amp;amp;shutdownFlag, 1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; case &amp;lt;-timeout:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.Exit(1)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; case err = &amp;lt;-complete:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;break&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Break the loop&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;break&lt;/b&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return err
&lt;/div&gt;
&lt;br /&gt;
Here I have an endless for loop waiting on three channels using a select statement.&lt;br /&gt;
&lt;br /&gt;
The first case is listening for an operating system Interrupt event. If the operating system requests the program to shutdown, this case will set a package level variable and continue back into the loop.&lt;br /&gt;
&lt;br /&gt;
The second case is listening for a timeout event. If the programs runs for 30 seconds, the timeout event will fire and the program will immediately terminate.&lt;br /&gt;
&lt;br /&gt;
The third case is listening for a complete event. If the Goroutine that is launched prior to entering the loop completes it work, it will notify the code on this channel. In this case we need to break out of both the case and the for loop.&lt;br /&gt;
&lt;br /&gt;
Fortunately there isn't any more logic to process outside of the select statement, so the second break statement works. If there were other cases that broke out of the select statement and did not require the loop to terminate, I would be in trouble. The code would require more logic and flags to determine when to break out of the loop and when to continue iterating.&lt;br /&gt;
&lt;br /&gt;
Go has an answer to this coding delima. You can define a label and break to that label.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
var err error&lt;br /&gt;
timeout := time.After(30 &amp;#42; time.Second)&lt;br /&gt;
&lt;br /&gt;
sigChan := make(chan os.Signal, 1)&lt;br /&gt;
signal.Notify(sigChan, os.Interrupt)&lt;br /&gt;
&lt;br /&gt;
complete := make(chan error)&lt;br /&gt;
go launchProcessor(complete)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Loop:
&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-sigChan:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;atomic.StoreInt32(&amp;amp;shutdownFlag, 1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-timeout:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.Exit(1)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case err = &amp;lt;-complete:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;break Loop&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
return err
&lt;/div&gt;
&lt;br /&gt;
I have changed the code a bit by declaring a label called Loop just above the for statement. Then in the last case, the break statement is provided the name of that label. This single call to break will jump the execution of the program outside of the for loop and to the next line of code. In this case, the next line of code is the call to return err.&lt;br /&gt;
&lt;br /&gt;
You can also use a label with a continue statement. This is a silly example but it shows you the mechanism:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;nbsp; &amp;nbsp; guestList := []string{&amp;quot;bill&amp;quot;, &amp;quot;jill&amp;quot;, &amp;quot;joan&amp;quot;}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; arrived := []string{&amp;quot;sally&amp;quot;, &amp;quot;jill&amp;quot;, &amp;quot;joan&amp;quot;}
&lt;br /&gt;
&lt;br /&gt;
CheckList:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for _, guest := range guestList {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for _, person := range arrived {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Guest[%s] Person[%s]\n&amp;quot;, guest, person)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if person == guest {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Let %s In\n&amp;quot;, person)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue CheckList&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }
&lt;/div&gt;
&lt;br /&gt;
Here is the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Guest[bill] Person[sally]&lt;br /&gt;
Guest[bill] Person[jill]&lt;br /&gt;
Guest[bill] Person[joan]&lt;br /&gt;
Guest[jill] Person[sally]&lt;br /&gt;
Guest[jill] Person[jill]&lt;br /&gt;
Let jill In&lt;br /&gt;
Guest[joan] Person[sally]&lt;br /&gt;
Guest[joan] Person[jill]&lt;br /&gt;
Guest[joan] Person[joan]
&lt;br /&gt;
Let joan in&lt;/div&gt;
&lt;br /&gt;
In this example there are two for loops, one nested inside the other. From the nested for loop, the continue statement uses a label to jump back to the outer for loop. From the output, you can see that the&lt;br /&gt;
outer for loop starts its next iteration. Once the outer for loop is complete, the execution of the program continues on.&lt;br /&gt;
&lt;br /&gt;
If you think this is just a fancy goto statement, it really isn't. The label being referenced must enclose the same for, switch or select statement. As you saw, the continue will still begin the next iteration of the for loop.&lt;br /&gt;
&lt;br /&gt;
Using label breaks and continues in these scenario keeps the code clean and precise.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Using The Log Package In Go</title><link>https://www.ardanlabs.com/blog/2013/11/using-log-package-in-go.html</link><pubDate>Tue, 05 Nov 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/11/using-log-package-in-go.html</guid><description>&lt;p&gt;Linux is unique to Windows in many ways, and writing programs in Linux is no exception. The use of standard out, standard err and null devices is not only a good idea but it&amp;rsquo;s the law. If your programs are going to be logging information, it is best to follow the destination conventions. This way your programs will work with all of the Mac/Linux tooling and hosted environments.&lt;br /&gt;
&lt;br /&gt;
Go has a package in the standard library called log and a type called logger. Using the log package will give you everything you need to be a good citizen. You will be able to write to all the standard devices, custom files or any destination that support the io.Writer interface.&lt;br /&gt;
&lt;br /&gt;
I have provided a really simple sample that will get you started with using logger:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Using XSLT With Go</title><link>https://www.ardanlabs.com/blog/2013/11/using-xslt-with-go.html</link><pubDate>Sun, 03 Nov 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/11/using-xslt-with-go.html</guid><description>&lt;p&gt;I am working on a project that requires pulling and processing different XML feeds from the web and storing the data into MongoDB as JSON. Since new feeds come up everyday, changing the Go program to process and publish new feeds is out of the question. A second constraint is that processing has to work in Iron.io or any other linux cloud based environment.&lt;br /&gt;
&lt;br /&gt;
What I needed was a Go program that could take an XML document and XSLT stylesheet at runtime, transform the XML into JSON and then store the JSON to MongoDB. I have some specific field names and other requirements for the JSON document that I need to make sure exist. XSLT makes this real easy to support.&lt;br /&gt;
&lt;br /&gt;
At first I looked at the different C libraries that exist. I figured I could integrate a library using CGO but after a few hours I realized this was not going to work. The libraries I found were huge and complex. Then by chance I found a reference about a program called xsltproc. The program exists both for the Mac and Linux operating systems. In fact, it comes pre-installed on the Mac and an apt-get will get you a copy of the program on your linux operating system.&lt;br /&gt;
&lt;br /&gt;
I have built a sample program that shows how to use xsltproc in your Go programs. Before we download the sample code we need to make sure you have xsltproc installed.&lt;br /&gt;
&lt;br /&gt;
If you are running on a Mac, xsltproc should already exist under /usr/bin&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Manage Dependencies With GODEP</title><link>https://www.ardanlabs.com/blog/2013/10/manage-dependencies-with-godep.html</link><pubDate>Sat, 26 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/10/manage-dependencies-with-godep.html</guid><description>&lt;h3&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h3&gt;
If you are using 3rd party packages, (packages that you don't own or control), you will want a way to create a reproducible build every time you build your projects. If you use 3rd party packages directly and the package authors change things, your projects could break. Even if things don't break, code changes could create inconsistent behavior and bugs.&lt;br /&gt;
&lt;br /&gt;
Keith Rarick's tool &lt;b&gt;godep&lt;/b&gt;&amp;nbsp;is a great step in the right direction for managing 3rd party dependencies and creating reproducible builds. The &lt;b&gt;godep&lt;/b&gt; tool gives you two options for managing dependencies. The first option creates a dependency file with version control information and then with some &lt;b&gt;godep&lt;/b&gt; magic,&amp;nbsp;the code is built against those versions. You can also Vendor your 3rd party packages inside your projects as well. You never need to change a single source code file and everything is accomplished in conjunction with the go tooling.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Downloading Godep&lt;/b&gt;&lt;/h3&gt;
Download &lt;b&gt;godep&lt;/b&gt;&amp;nbsp;using go get and make sure your $GOPATH/bin directory is in your PATH.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
go get github.com/kr/godep&lt;br /&gt;
export PATH=$PATH:$GOPATH/bin&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Create A Project&lt;/b&gt;&lt;/h3&gt;
Build your project using the 3rd party packages as you normally would. Since &lt;b&gt;godep&lt;/b&gt; does not require you to change any import paths in the code, 'go get' the code you need and import those packages directly. To keep the post simple, I am going to use an existing program called News Search that uses one 3rd party dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
export GOPATH=$HOME/example&lt;br /&gt;
go get github.com/goinggo/newssearch&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2013-10-26+at+8.41.33+AM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2013-10-26+at+8.41.33+AM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>My Channel Select Bug</title><link>https://www.ardanlabs.com/blog/2013/10/my-channel-select-bug.html</link><pubDate>Thu, 17 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/10/my-channel-select-bug.html</guid><description>&lt;p&gt;I was testing new functionality on a program that is already running in production when suddenly the code behaved very badly. What I saw shocked me and then it became obvious why it happened. I also have a race condition just waiting to be a problem.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;I have tried to provide a simplified version of the code and the two bugs.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os/signal&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;time&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
var Shutdown bool = false&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sigChan := make(chan os.Signal, 1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; signal.Notify(sigChan, os.Interrupt)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-sigChan:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Shutdown = true&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-func() chan struct{} {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; complete := make(chan struct{})&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; go LaunchProcessor(complete)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return complete&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }():&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func LaunchProcessor(complete chan struct{}) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; close(complete)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Start Work\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for count := 0; count &amp;lt; 5; count++ {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Doing Work\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; time.Sleep(1 &amp;#42; time.Second)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if Shutdown == true {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Kill Early\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;End Work\n&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
The idea behind this code is to run a task and terminate. It allows the operating system to request the program to terminate early. I always like shutting down the program cleanly when possible.&lt;br /&gt;
&lt;br /&gt;
The sample code creates a channel that is bound to an operating system signal and looks for &amp;lt;ctrl&amp;gt; C from the terminal window. If &amp;lt;ctrl&amp;gt; C is issued, the Shutdown flag is set to true and the program continues back into the select statement. The code also spawns a Go routine that performs the work. That routine checks the Shutdown flag to determine if the program needs to terminate early.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Bug Number 1&lt;/h3&gt;
Take a look at this part of the code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
case &amp;lt;-func() chan struct{} {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; complete := make(chan struct{})&lt;br /&gt;
&amp;nbsp; &amp;nbsp; go LaunchProcessor(complete)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return complete&lt;br /&gt;
}():
&lt;/div&gt;
&lt;br /&gt;
I thought I was being so clever when I wrote this code. I thought it would be cool to execute a function on the fly to spawn the Go routine. It returns a channel that the select waits on to be told the work is complete. When the Go routine is done it closes the channel and the program terminates.&lt;br /&gt;
&lt;br /&gt;
Let's run the program:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Work&lt;br /&gt;
Doing Work&lt;br /&gt;
Doing Work&lt;br /&gt;
Doing Work&lt;br /&gt;
Doing Work&lt;br /&gt;
Doing Work&lt;br /&gt;
End Work
&lt;/div&gt;
&lt;br /&gt;
As expected the program starts and spawns the Go routine. Once the Go routine is complete the program terminates.&lt;br /&gt;
&lt;br /&gt;
This time I will hit &amp;lt;ctlr&amp;gt; C while the program is running:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&lt;b&gt;Start Work&lt;/b&gt;&lt;br /&gt;
Doing Work&lt;br /&gt;
^C&lt;b&gt;Start Work&lt;/b&gt;&lt;br /&gt;
Doing Work&lt;br /&gt;
Kill Early&lt;br /&gt;
Kill Early
&lt;/div&gt;
&lt;br /&gt;
When I hit &amp;lt;ctrl&amp;gt; C the program launched the Go routine again!!&lt;br /&gt;
&lt;br /&gt;
I thought that the function associated with the case would only be executed once. Then the select would just wait on the channel moving forward. I had no idea that the function would be executed every time the loop iterated back to the select statement.&lt;br /&gt;
&lt;br /&gt;
To fix the code I needed to remove the function out of the select statement and spawn the Go routine outside of the loop:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sigChan := make(chan os.Signal, 1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; signal.Notify(sigChan, os.Interrupt)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;complete := make(chan struct{})&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; go LaunchProcessor(complete)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-sigChan:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Shutdown = true&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;case &amp;lt;-complete:&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Now when we run the program we get a better result:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Work&lt;br /&gt;
Doing Work&lt;br /&gt;
Doing Work&lt;br /&gt;
^CKill Early
&lt;/div&gt;
&lt;br /&gt;
This time when I hit &amp;lt;ctrl&amp;gt; C the program terminate early and doesn't spawn another Go routine again.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Bug Number 2&lt;/h3&gt;
There is a second less obvious bug lurking in the code as well. Take a look at these pieces of code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
var Shutdown bool = false&lt;br /&gt;
&lt;br /&gt;
if whatSig == syscall.SIGINT {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Shutdown = true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if Shutdown == true {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Kill Early\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The code is using a package level variable to signal the running Go routine to shut down when &amp;lt;ctrl&amp;gt; C is hit. The code is working every time I hit &amp;lt;ctrl&amp;gt; C so why is there a bug?&lt;br /&gt;
&lt;br /&gt;
First let's run the race detector against the code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
go build -race&lt;br /&gt;
./test&lt;/div&gt;
&lt;br /&gt;
While it is running I hit &amp;lt;ctrl&amp;gt; C again:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Work&lt;br /&gt;
Doing Work&lt;br /&gt;
^C==================&lt;br /&gt;
WARNING: DATA RACE&lt;br /&gt;
Read by goroutine 5:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; main.LaunchProcessor()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/Spaces/Test/src/test/main.go:46 +0x10b&lt;br /&gt;
&amp;nbsp; &amp;nbsp; gosched0()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/go/src/pkg/runtime/proc.c:1218 +0x9f&lt;br /&gt;
&lt;br /&gt;
Previous write by goroutine 1:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; main.main()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/Spaces/Test/src/test/main.go:25 +0x136&lt;br /&gt;
&amp;nbsp; &amp;nbsp; runtime.main()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/go/src/pkg/runtime/proc.c:182 +0x91&lt;br /&gt;
&lt;br /&gt;
Goroutine 5 (running) created at:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; main.main()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/Spaces/Test/src/test/main.go:18 +0x8f&lt;br /&gt;
&amp;nbsp; &amp;nbsp; runtime.main()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/go/src/pkg/runtime/proc.c:182 +0x91&lt;br /&gt;
&lt;br /&gt;
Goroutine 1 (running) created at:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; _rt0_amd64()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /Users/bill/go/src/pkg/runtime/asm_amd64.s:87 +0x106&lt;br /&gt;
&lt;br /&gt;
==================&lt;br /&gt;
Kill Early&lt;br /&gt;
Found 1 data race(s)
&lt;/div&gt;
&lt;br /&gt;
My use of the Shutdown flag comes up on the race detector. This is because I have two Go routines trying to access the variable in an unsafe way.&lt;br /&gt;
&lt;br /&gt;
My initial reason for not securing access to the variable was practical but wrong. I figured that since the variable is only used to shutdown the program when it becomes necessary, I didn't care about a dirty read. If by chance, within the microsecond of glare there was between writing to the variable and reading the variable, if a dirty read occurred, I would catch it again on the next loop. No harm done, right? &amp;nbsp;Why add complicated channel or locking code for something like this?&lt;br /&gt;
&lt;br /&gt;
Well, there is a little thing called the Go Memory Model.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/ref/mem" target="_blank"&gt;http://golang.org/ref/mem&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The Go Memory Model does not guarantee that the Go routine reading the Shutdown variable will ever see the write by the main routine. It is valid for the write to the Shutdown variable by the main routine to never be written back to main memory. This is because the main routine never reads the Shutdown variable.&lt;br /&gt;
&lt;br /&gt;
This is not happening today but as the Go compiler becomes more sophisticated it could decide to eliminate the write to the Shutdown variable altogether. This behavior is allowed by the Go Memory Model. Also, we don't want code that can't pass the race detector, it is just bad practice, even for practical reasons.&lt;br /&gt;
&lt;br /&gt;
Here is a final version of the code with all bugs fixed:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os/signal&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;sync/atomic&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;time&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;var Shutdown int32 = 0&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sigChan := make(chan os.Signal, 1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; signal.Notify(sigChan, os.Interrupt)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;complete := make(chan struct{})&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; go LaunchProcessor(complete)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; select {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case &amp;lt;-sigChan:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;atomic.StoreInt32(&amp;amp;Shutdown,&lt;span style="color: #f57900;"&gt; &lt;/span&gt;1)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;case &amp;lt;-complete:&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func LaunchProcessor(complete chan struct{}) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; close(complete)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Start Work\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for count := 0; count &amp;lt; 5; count++ {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Doing Work\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; time.Sleep(1 &amp;#42; time.Second)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;if&amp;nbsp;atomic.LoadInt32(&amp;amp;Shutdown)&lt;span style="color: #f57900;"&gt; &lt;/span&gt;==&lt;span style="color: #f57900;"&gt; &lt;/span&gt;1&lt;/b&gt;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Kill Early\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;End Work\n&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
I prefer to use an if statement to check if the Shutdown flag is set so I can sprinkle that code as needed. This solution changes the Shutdown flag from a boolean value to an int32 and uses the atomic functions Store and Load.&lt;br /&gt;
&lt;br /&gt;
In the main routine if a &amp;lt;ctrl&amp;gt; C is detected, the Shutdown flag is safely changed from 0 to 1. In the LaunchProcessor Go routine, the value of the Shutdown flag is compared to 1. If that condition is true the Go routine returns.&lt;br /&gt;
&lt;br /&gt;
It's amazing sometimes how a simple program like this can contain a few gotchas. Things you may have never thought about or realized when you started. Especially when the code always seems to work.&lt;br /&gt;</description></item><item><title>Functions and Naked Returns In Go</title><link>https://www.ardanlabs.com/blog/2013/10/functions-and-naked-returns-in-go.html</link><pubDate>Thu, 10 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/10/functions-and-naked-returns-in-go.html</guid><description>&lt;p&gt;In Go values that are returned from functions are passed by value. Go gives you some nice flexibility when it comes to returning values from a function.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here is a simple example of returning two values from a function:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id, err := ReturnId()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;ERROR: %s&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;Id: %d\n&amp;quot;, id)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func ReturnId() (int, error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id := 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return id, nil&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The function ReturnId returns a value of type integer and of type error. This is something very common that is done in Go. Error handling is performed by returning a value of type error from your functions and the calling function evaluating that value before continuing.&lt;br /&gt;
&lt;br /&gt;
If you don't care about the error for some reason after a function call returns, you can do something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;nbsp; &amp;nbsp;id, _ := ReturnId()&lt;/div&gt;
&lt;br /&gt;
This time I used an underscore to represent the return value for the second return argument, which was the error. This is really nice because I don't need to declare a variable to hold the value being passed in, I can simply ignore it.&lt;br /&gt;
&lt;br /&gt;
You also have the option to name your return arguments:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return id, err&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
If you name your return arguments you are creating local variables just like with your function parameters. This time when I set the id variable, I remove the colon (:) from the short variable declaration and convert it to an assignment operation. Then in the return I specify the return variables as normal.&lt;br /&gt;
&lt;br /&gt;
Naming your return arguments is a nice way to document what you are returning. There is also something else that you can do with your named arguments, or not do:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;b&gt;return&lt;/b&gt;&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
This is what is called a naked return. I have removed the arguments from the return statement. The Go compiler automatically returns the current values in the return arguments local variables. Though this is really cool you need to watch for shadowing:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;if id == 10 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; err := fmt.Errorf(&amp;quot;Invalid Id\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
If you try to compile this you will get the following compiler error:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
err is shadowed during return
&lt;/div&gt;
&lt;br /&gt;
To understand why this error exists you need to understand what curly bracket do inside of a function. Each set of curly brackets define a new level of scope. Take this code for example:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id := 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id := 20&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;Id: %d\n&amp;quot;, id)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
If you try to compile this code you get the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
no new variables on left side of :=
&lt;/div&gt;
&lt;br /&gt;
This makes sense because you are trying to declare the same variable name twice. The error goes away if we change the code to look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id := 10&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;id := 20&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;Id: %d\n&amp;quot;, id)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;Id: %d\n&amp;quot;, id)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The curly brackets define a new stack frame and therefore a new level of scope. The variable name can be reused inside the new set of curly brackets. When the code reaches the closing curly bracket that small piece of the stack is popped.&lt;br /&gt;
&lt;br /&gt;
Look again at the code that caused the shadowing error:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;if id == 10 &lt;b&gt;{&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;err := fmt.Errorf(&amp;quot;Invalid Id\n&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;b&gt;}&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Inside the if statement we are creating a new variable called err. We are not using the err variable declared as the function return argument. The compiler recognizes this and produces the error. If the compiler did not report this error, you would never see the error that occured inside the if statement. The return err variable is what is passed by default&lt;br /&gt;
&lt;br /&gt;
Naming your return arguments come in real handy when using a defer statement:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if id == 10 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;err = fmt.Errorf(&amp;quot;Invalid Id\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Because the return arguments are named, you can reference them in the defer function. You can even change the value of the return arguments inside the defer call and the calling function will see the new values. This version will display the error message.&lt;br /&gt;
&lt;br /&gt;
You need to be aware that the defer statement is evaluated inline with the rest of the code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReturnId() (id int, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;defer func(id int) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if id == 10 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;err = fmt.Errorf(&amp;quot;Invalid Id\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}(id)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id = 10&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
This version does not display the error message. The value of id is not 10 until after the defer statement is evaluated.&lt;br /&gt;
&lt;br /&gt;
Sometimes it makes sense to use named return arguments, such when using a defer statement at the top of your function. If you are passing raw values out of your function then something like this does not make sense:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;ans := AddNumbers(10, 12)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;fmt.Printf(&amp;quot;Answer: %d\n&amp;quot;, ans)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func AddNumbers(a int, b int) (result int) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;return a + b&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The return argument is named for the AddNumbers function but never used. Instead we return the answer of the operation directly out of the return. This shows you how you can still return any value you want even if you name the return arguments.&lt;br /&gt;
&lt;br /&gt;
I asked the Go community for their opinions about using named arguments and naked returns:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://plus.google.com/107537752159279043170/posts/8hMjHhmyNk2" target="_blank"&gt;https://plus.google.com/107537752159279043170/posts/8hMjHhmyNk2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I got a very good mix of opinions that I think everyone should read. Go gives you a lot of flexibility and choice when building your functions. Don't look for a single common practice for everything. Take each function individually and implement the best construct for that use case.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Cross Compile Your Go Programs</title><link>https://www.ardanlabs.com/blog/2013/10/cross-compile-your-go-programs.html</link><pubDate>Wed, 02 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/10/cross-compile-your-go-programs.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
In my post about building and running programs in &lt;a href="https://www.ardanlabs.com/blog/2013/09/running-go-programs-in-ironworker.html" target="_blank"&gt;Iron.Io&lt;/a&gt;, I needed to switched over to my Ubuntu VM to build linux versions of my test programs locally. I love the ability to have Ubuntu available to me for building and testing my code. However, if I can stay on the Mac side it is better.&lt;br /&gt;
&lt;br /&gt;
I have wanted to learn how to cross compile my Go programs for the two platforms I use, darwin/amd64 and linux/amd64. This way I could create final builds of my programs and publish everything from my Mac OS. After a couple of hours I am finally able to do this.&lt;br /&gt;
&lt;br /&gt;
If you don&amp;rsquo;t have the need to cross compile your code then I recommend you stick with the traditional distribution packages and installs for Go. If this is something you need, then it all starts with downloading the current release of the Go source code.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Installing Git&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
The Go source code is stored in a DVCS called Github and is located on &lt;a href="http://github.com/golang/go" target="_blank"&gt;github.com/golang/go&lt;/a&gt;. The first thing you need to do is install Git if you don&amp;rsquo;t already have it.&lt;br /&gt;
&lt;br /&gt;
Go to the download page on the Git website:  &lt;a href="http://git-scm.com/downloads"&gt;http://git-scm.com/downloads&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Go Package Management Call To Action</title><link>https://www.ardanlabs.com/blog/2013/10/go-package-management-call-to-action.html</link><pubDate>Tue, 01 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/10/go-package-management-call-to-action.html</guid><description>&lt;div class="p1"&gt;
Nathan Youngman, with the help of others, has produced this document outlining months of research and discovery. I would appreciate everyone to honestly read it before continuing with my post.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span class="s1"&gt;&lt;a href="http://nathany.com/go-packages/" target="_blank"&gt;http://nathany.com/go-packages/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
Mitchell Hashimoto&amp;nbsp;also published this post on go-nuts and everyone should read this as well.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span class="s1"&gt;&lt;a href="https://groups.google.com/forum/#!msg/golang-nuts/BMZDD6FM-QE/LX4JSs4NVLIJ" target="_blank"&gt;https://groups.google.com/forum/#!msg/golang-nuts/BMZDD6FM-QE/LX4JSs4NVLIJ&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
These two documents outline the current capabilities and issues surrounding the Go tooling as it relates to package management. This has been discussed and discussed at length yet we still don't have a consensus on what the community will rally around.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
I am willing to perform all the administrative work involved in putting together a specification and working reference implementation. If we can accomplish this, then we have something that can be used by the community to build a package management tool and we all win.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
I have created a Google Group and I ask those of you who are interested to join.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span class="s1"&gt;&lt;a href="https://groups.google.com/forum/#!forum/go-package-management" target="_blank"&gt;https://groups.google.com/forum/#!forum/go-package-management&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
The group is public. If you are interested in being a part of the working group please submit your request at the group.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Our goal is to present our&amp;nbsp;specification&amp;nbsp;and working reference implementation to the community at GopherCon in April 2014.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
The first step will be to define a set of milestones that allow us to meet our goals by April next year. Then we need to organize the working group into teams with team leaders and members to help do the research and make recommendations.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
I hope some of you consider joining the group and help the community solve this problem.&lt;/div&gt;
&lt;br /&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;</description></item><item><title>Detecting Race Conditions With Go</title><link>https://www.ardanlabs.com/blog/2013/09/detecting-race-conditions-with-go.html</link><pubDate>Thu, 26 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/detecting-race-conditions-with-go.html</guid><description>&lt;p&gt;I always find it interesting when I realize that something I have been practicing or dealing with for a long time has a name. This time it happens to be race conditions. This is something you can&amp;rsquo;t avoid thinking about as soon as you have more than one routine sharing any kind of resource. If you&amp;rsquo;re not thinking about race conditions in your code, now is the time.&lt;br /&gt;
&lt;br /&gt;
A race condition is when two or more routines have access to the same resource, such as a variable or data structure and attempt to read and write to that resource without any regard to the other routines. This type of code can create the craziest and most random bugs you have ever seen. It usually takes a tremendous amount of logging and luck to find these types of bugs. Over the years I have really perfected my logging skills to help identify these problems when they occur.&lt;br /&gt;
&lt;br /&gt;
Back in June with Go version 1.1, the Go tooling introduced a race detector. The race detector is code that is built into your program during the build process. Then once your program is running, it is able to detect and report any race conditions it finds. It is seriously cool and does an incredible job in identifying the code that is the culprit.&lt;br /&gt;
&lt;br /&gt;
Let&amp;rsquo;s take a very simple program that contains a race condition and build the code with the race detector.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Recursion And Tail Calls In Go</title><link>https://www.ardanlabs.com/blog/2013/09/recursion-and-tail-calls-in-go_26.html</link><pubDate>Thu, 26 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/recursion-and-tail-calls-in-go_26.html</guid><description>&lt;p&gt;&lt;i style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;"&gt;This article was written for and published by &lt;a href="http://www.gopheracademy.com/" target="_blank"&gt;Gopher Academy&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;
&lt;br /&gt;
I was looking at a code sample that showed a recursive function in Go and the writer was very quick to state how Go does not optimize for recursion, even if tail calls are explicit. I had no idea what a tail call was and I really wanted to understand what he meant by Go was not optimized for recursion. I didn't know recursion could be optimized.&lt;br /&gt;
&lt;br /&gt;
For those who don't know what recursion is, put simply, it is when a function calls itself. Why would we ever write a function that would call itself? Recursion is great for algorithms that perform operations on data that can benefit from using a stack, FILO (First In Last Out). It can be faster than using loops and can make your code much simpler.&lt;br /&gt;
&lt;br /&gt;
Performing math operations where the result of a calculation is used in the next calculation is a classic example where recursion shines. As with all recursion, you must have an anchor that eventually causes the function to stop calling itself and return. If not, you have an endless loop that eventually will cause a panic because you will run out of memory.&lt;br /&gt;
&lt;br /&gt;
Why would you run out of memory? In a traditional C program, stack memory is used to handle all the coming and going of function calls. The stack is pre-allocated memory and very fast to use. Look at the following diagram:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2013-09-20+at+5.20.24+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2013-09-20+at+5.20.24+PM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Iterating Over Slices In Go</title><link>https://www.ardanlabs.com/blog/2013/09/iterating-over-slices-in-go.html</link><pubDate>Mon, 23 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/iterating-over-slices-in-go.html</guid><description>&lt;p&gt;Slices are used everywhere in my code. If I am working with data from MongoDB, it is stored in a slice. If I need to keep track of a collection of problems after running an operation, it is stored in a slice. If you don&amp;rsquo;t understand how slices work yet or have been avoiding them like I did when I started, read these two posts to learn more.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html"&gt;&lt;a href="https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html"&gt;https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html&lt;/a&gt;&lt;/a&gt; &lt;br /&gt;
&lt;a href="https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html"&gt;&lt;a href="https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html"&gt;https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Pool Go Routines To Process Task Oriented Work</title><link>https://www.ardanlabs.com/blog/2013/09/pool-go-routines-to-process-task.html</link><pubDate>Sat, 14 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/pool-go-routines-to-process-task.html</guid><description>&lt;p&gt;&lt;i&gt;After working in Go for some time now, I learned how to use an unbuffered channel to build a pool of goroutines. I like this implementation better than what is implemented in this post.  That being said, this post still has value in what it describes.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;a href="https://github.com/goinggo/work" target="_blank"&gt;&lt;a href="https://github.com/goinggo/work"&gt;https://github.com/goinggo/work&lt;/a&gt;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
On more than one occasion I have been asked why I use the Work Pool pattern. Why not just start as many Go routines as needed at any given time to get the work done? My answer is always the same. Depending on the type of work, the computing resources you have available and the constraints that exist within the platform, blindly throwing Go routines to perform work could make things slower and hurt overall system performance and responsiveness.&lt;br /&gt;
&lt;br /&gt;
Every application, system and platform has a breaking point. Resources are not unlimited, whether that is memory, CPU, storage, bandwidth, etc. The ability for our applications to reduce and reuse resources is important. Work pools provide a pattern that can help applications manage resources and provide performance tuning options.&lt;br /&gt;
&lt;br /&gt;
Here is the pattern behind the work pool:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Slices of Slices of Slices in Go</title><link>https://www.ardanlabs.com/blog/2013/09/slices-of-slices-of-slices-in-go.html</link><pubDate>Tue, 10 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/slices-of-slices-of-slices-in-go.html</guid><description>&lt;p&gt;I am working on building code to load polygons for the different Marine Forecast areas in the United States. These polygons need to be stored in MongoDB and there is a special way that needs to be done. It would not have been a big deal if it wasn&amp;rsquo;t for this fact. There isn&amp;rsquo;t just one polygon for each area. There is an external polygon and then zero to many interior polygons that need to be stored in relationship.&lt;br /&gt;
&lt;br /&gt;
After staring at the problem for a bit I realized that I needed to create a slice of Marine Forecast areas, each of which contained a slice of polygons. To store each polygon ring I needed a slice of geographic coordinates. Finally each coordinate needed to be stored in a two dimensional array of floats.&lt;br /&gt;
&lt;br /&gt;
A picture is worth a thousand words:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Running Go Programs In IronWorker</title><link>https://www.ardanlabs.com/blog/2013/09/running-go-programs-in-ironworker.html</link><pubDate>Sat, 07 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/running-go-programs-in-ironworker.html</guid><description>&lt;p&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Iron.io has a product called IronWorker which provides a task oriented Linux container that you can run your programs inside. If you are not sure what I mean, think of this as having a temporary Linux virtual machine instantly available for your personal but short term use. IronWorker allows you to load your binaries, code files, support files, shells scripts and just about anything else you may need to run your program in the container. You specify a single task to execute, such as running a shell script or a binary and IronWorker will perform that task when requested. Once the task is complete, IronWorker will tear down the container as if it never existed.&lt;br /&gt;
&lt;br /&gt;
If you are developing in Windows or on the Mac and plan to load and run pre-built binaries in IronWorker, they must be built for Linux. If that could be a problem don&amp;rsquo;t despair, you have options.&lt;br /&gt;
&lt;br /&gt;
You can create an Ubuntu VM so you can build the Linux binaries you need. This is what I do. I don&amp;rsquo;t develop in my Ubuntu VM, I use it as a testing and staging area. Your second option is to build your program inside of the IronWorker container and then execute it. You have a lot of flexibility to do what you need with IronWorker.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Timer Routines And Graceful Shutdowns In Go</title><link>https://www.ardanlabs.com/blog/2013/09/timer-routines-and-graceful-shutdowns.html</link><pubDate>Wed, 04 Sep 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/09/timer-routines-and-graceful-shutdowns.html</guid><description>&lt;p&gt;In my Outcast data server I have several data retrieval jobs that run using different go routines. Each routine wakes up on a set interval. The most complex job is the downloading of radar images. What makes this complex is that there are 155 radar stations throughout the United States that take a new picture every 120 seconds. All these radar images can be put together to create a mosaic. When the go routine wakes up to pull down the new images, it must do this as quickly as possible for all 155 stations. If it doesn&amp;rsquo;t, the mosaics will be out of sync and any overlays across station boundaries will look off.&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Using CGO with Pkg-Config And Custom Dynamic Library Locations</title><link>https://www.ardanlabs.com/blog/2013/08/using-cgo-with-pkg-config-and-custom.html</link><pubDate>Sat, 31 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/using-cgo-with-pkg-config-and-custom.html</guid><description>&lt;p&gt;Earlier in the month I wrote a post about using &lt;a href="https://www.ardanlabs.com/blog/2013/08/using-c-dynamic-libraries-in-go-programs.html" target="_blank"&gt;C Dynamic Libraries in Go Programs&lt;/a&gt;. The article built a dynamic library in C and created a Go program that used it. The program worked but only if the dynamic library was in the same folder as the program.&lt;br /&gt;
&lt;br /&gt;
This constraint does not allow for the use of the &lt;b&gt;go get&lt;/b&gt; command to download, build and install a working version of the program. I did not want to have any requirements to pre-install dependencies or run extra scripts or commands after the call to&lt;b&gt; go get&lt;/b&gt;. The Go tool was not going to copy the dynamic library into the bin folder and therefore I would not be able to run the program once the &lt;b&gt;go get &lt;/b&gt;command was complete. This was simply unacceptable and there had to be a way to make this work.&lt;br /&gt;
&lt;br /&gt;
The solution to this problem was twofold. First, I needed to use a package configuration file to specify the compiler and linker options to CGO. Second, I needed to set an environment variable so the operating system could find the dynamic library without needing to copy it to the bin folder.&lt;br /&gt;
&lt;br /&gt;
If you look, you will see that some of the standard libraries provide a package configuration (.pc) file. A special program called &lt;b&gt;pkg-config&lt;/b&gt; is used by the build tools, such as gcc, to retrieve information from these files.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Organizing Code to Support Go Get</title><link>https://www.ardanlabs.com/blog/2013/08/organizing-code-to-support-go-get.html</link><pubDate>Wed, 28 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/organizing-code-to-support-go-get.html</guid><description>&lt;p&gt;For those of you who are like me, trying to learn the Mac and Linux operating systems, Golang programming and deployment constructs all at the same time, I feel your pain. I have been building a Go application for a couple of months on my Mac and it was time to deploy the code on a local Ubuntu server. I was having a really tough time and it was turning into a disaster. Like always, I kept telling myself, I must be doing something wrong.&lt;br /&gt;
&lt;br /&gt;
Well, I was, big-time. Let me put it this way. After spending 2 days reorganizing repositories and code, I finally figured out how the Go tool works. Now I can update my development environment, deploy, build, install and update my Go applications on any machine with one simple call to &lt;b&gt;go get&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
I am sure there are several ways you can organize code that will work with the Go tool. What I am going to present is working for me and I wish I knew all of this when I started. There are a 1000 ways to skin a cat and we all have our favorite way, this one is now mine.&lt;br /&gt;
&lt;br /&gt;
Everything we do in Go should be based on what the Go tool can do. Going off the reservation will get you in trouble, I am living proof. One special command we are going to focus on is&lt;b&gt; get&lt;/b&gt;. The &lt;b&gt;get&lt;/b&gt; command will download code, build and install packages and produce an executable binary if you are building a program. It is very smart and can read your code to find dependences that it will download, built and install as well. That is, if everything is structured and set correctly.&lt;br /&gt;
&lt;br /&gt;
This document explains all the things the Go tool can do:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/cmd/go/" target="_blank"&gt;&lt;a href="http://golang.org/cmd/go/"&gt;http://golang.org/cmd/go/&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
But I want to concentrate on this section:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/cmd/go/#hdr-Remote_import_path_syntax" target="_blank"&gt;&lt;a href="http://golang.org/cmd/go/#hdr-Remote_import_path_syntax"&gt;http://golang.org/cmd/go/#hdr-Remote_import_path_syntax&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Even as I read this document now I have a hard time understanding what it is trying to tell me.&lt;br /&gt;
&lt;br /&gt;
I use Github but you don&amp;rsquo;t have to. The Go tool supports Github, Mercurial, Subversion and Bazaar out of the box. If you are not using any of these systems for version control, there are ways to give the Go tool the information it needs to support your version control system.&lt;br /&gt;
&lt;br /&gt;
When I say the Go tool supports these version control systems it&amp;rsquo;s a bit vague right now, so let&amp;rsquo;s jump into this. Everything starts with a repository, so let&amp;rsquo;s look at the ones I have for my project. I have two accounts in Github. One is called &lt;b&gt;goinggo&lt;/b&gt; which contains all my shared and reusable repositories. The other is &lt;b&gt;ArdanStudios&lt;/b&gt; which contains my private repositories.&lt;br /&gt;
&lt;br /&gt;
Here is the &lt;b&gt;goinggo&lt;/b&gt; repository:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Collections Of Unknown Length in Go</title><link>https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html</link><pubDate>Mon, 26 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/collections-of-unknown-length-in-go.html</guid><description>&lt;p&gt;If you are coming to Go after using a programming language like C# or Java, the first thing you will discover is that there are no traditional collection types like List and Dictionary. That really threw me off for months. I found a package called container/list and gravitated to using it for almost everything.&lt;br /&gt;
&lt;br /&gt;
Something in the back of my head kept nagging me. It didn&amp;rsquo;t make any sense that the language designers would not directly support managing a collection of unknown length. Everyone talks about how slices are widely used in the language and here I am only using them when I have a well defined capacity or they are returned to me by some function. Something is wrong!!&lt;br /&gt;
&lt;br /&gt;
So I wrote an article earlier in the month that took the covers off of slices in a hope that I would find some magic that I was missing. I now know how slices work but at the end of the day, I still had an array that would have to grow. I was taught in school that linked lists were more efficient and gave you a better way to store large collections of data. Especially when the number of items you need to collect is unknown. It made sense to me.&lt;br /&gt;
&lt;br /&gt;
When I thought about using an empty slice, I had this very WRONG picture in my head:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Using C Dynamic Libraries In Go Programs</title><link>https://www.ardanlabs.com/blog/2013/08/using-c-dynamic-libraries-in-go-programs.html</link><pubDate>Tue, 20 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/using-c-dynamic-libraries-in-go-programs.html</guid><description>&lt;p&gt;My son and I were having fun last weekend building a console based game in Go. I was recreating a game from my youth, back when I was programming on a Kaypro II.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div class="separator"&gt;
&lt;/div&gt;
&lt;div class="separator"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/kayproii.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/kayproii.jpg" alt="kayproii"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
&lt;br /&gt;
I loved this computer. I would write games in BASIC on it all day and night. Did I mention it was portable. The keyboard would strap in and you could carry it around. LOL.
&lt;br /&gt;
&lt;br /&gt;
But I digress, back to my Go program. I figured out a way to use the VT100 escape character codes to draw out a simple screen and started programming some of the logic.
&lt;br /&gt;
&lt;br /&gt;
Then something horrible happened and I had a major flashback. I could not get input from stdin without hitting the enter key. Ahhhhh &amp;nbsp;I spent all weekend reading up on how to make this happen. I even found two Go libraries that had support for this but they didn't work. I realized that if I was going to make this happen I needed to build the functionality in C and link that to my Go program.
&lt;br /&gt;
&lt;br /&gt;
After a 4 hour coding session at the local Irish pub, I figured it out. I would like to thank Guinness for the inspiration and encouragement I needed. Understand that for the past 10 years I have been writing windows services in C#. For 10 years before that I was writing C/C++ but on the Microsoft stack. Everything I was reading: gcc, gco, static and shared libraries on the Mac and Linux, etc, was foreign to me. I had a lot to learn and still do.
&lt;br /&gt;
&lt;br /&gt;
After all my research it became clear I needed to use the ncurses dynamic library. I decided to write a simple program in C using the library. If I could make it work in a compiled C program, I was sure I could get it to work in Go.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator"&gt;
&lt;p&gt;&lt;a href="../../../images/goinggo/Screen+Shot+2013-08-20+at+1.57.49+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img src="../../../images/goinggo/Screen+Shot+2013-08-20+at+1.57.49+PM.png" alt="Screen Shot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Understanding Slices in Go Programming</title><link>https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html</link><pubDate>Thu, 15 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/understanding-slices-in-go-programming.html</guid><description>&lt;p&gt;Since I started programming in Go the concept and use of slices has been confusing. This is something completely new to me. They look like an array, and feel like an array, but they are much more than an array. I am constantly reading how slices are used quite a bit by Go programmers and I think it is finally time for me to understand what slices are all about.&lt;/p&gt;</description></item><item><title>Using Time, Timezones and Location in Go</title><link>https://www.ardanlabs.com/blog/2013/08/using-time-timezones-and-location-in-go.html</link><pubDate>Thu, 08 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/using-time-timezones-and-location-in-go.html</guid><description>&lt;p&gt;I ran into a problem today. I was building code to consume NOAA&amp;rsquo;s tide station XML document and quickly realized I was in trouble. Here is a small piece of that XML document:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&lt;b&gt;&amp;lt;timezone&amp;gt;LST/LDT&amp;lt;/timezone&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;item&amp;gt;&lt;br /&gt;
&lt;b&gt;&amp;lt;date&amp;gt;2013/01/01&amp;lt;/date&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;day&amp;gt;Tue&amp;lt;/day&amp;gt;&lt;br /&gt;
&lt;b&gt;&amp;lt;time&amp;gt;02:06 AM&amp;lt;/time&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;predictions_in_ft&amp;gt;19.7&amp;lt;/predictions_in_ft&amp;gt;&lt;br /&gt;
&amp;lt;predictions_in_cm&amp;gt;600&amp;lt;/predictions_in_cm&amp;gt;&lt;br /&gt;
&amp;lt;highlow&amp;gt;H&amp;lt;/highlow&amp;gt;&lt;br /&gt;
&amp;lt;/item&amp;gt;
&lt;/div&gt;
&lt;br /&gt;
If you notice the timezone tag, it states the time is in Local Standard Time / Local Daylight Time. This is a real problem because I need to store this data in UTC. Without a proper timezone I am lost. After scratching my head for a bit my business partner showed me two API's that take a latitude and longitude position and return timezone information. Luckily for me I have a latitude and longitude position for each tide station.&lt;br /&gt;
&lt;br /&gt;
If you open this web page you can read the documentation for Google's Timezone API:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://developers.google.com/maps/documentation/timezone/" target="_blank"&gt;https://developers.google.com/maps/documentation/timezone/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The API is fairly simple. It requires a location, timestamps and a flag to identify if the requesting application is using a sensor, like a GPS device, to determine the location.&lt;br /&gt;
&lt;br /&gt;
Here is a sample call to the Google API and response:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
https://maps.googleapis.com/maps/api/timezone/json?location=38.85682,-92.991714&amp;amp;sensor=false&amp;amp;timestamp=1331766000&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;dstOffset&amp;quot; : 3600.0,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;rawOffset&amp;quot; : -21600.0,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;status&amp;quot; : &amp;quot;OK&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;timeZoneId&amp;quot; : &amp;quot;America/Chicago&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;timeZoneName&amp;quot; : &amp;quot;Central Daylight Time&amp;quot;&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
There is a limit of 2,500 calls a day. For my initial load of the tide stations, I knew I was going to hit that limit and I didn't want to wait several days to load all the data. So my business partner found the timezone API from GeoNames.&lt;br /&gt;
&lt;br /&gt;
If you open this web page you can read the documentation for GeoNames's Timezone API:&lt;br /&gt;
&lt;br /&gt;
[http://www.geonames.org/export/web-services.html#timezone](/broken-link)&lt;br /&gt;
&lt;br /&gt;
The API requires a free account which is real quick to setup. Once you activate your account you need to find the account page and activate your username for use with the API.&lt;br /&gt;
&lt;br /&gt;
Here is a sample call to the GeoNames API and response:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
http://api.geonames.org/timezoneJSON?lat=47.01&amp;amp;lng=10.2&amp;amp;username=demo&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;time&amp;quot;:&amp;quot;2013-08-09 00:54&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;countryName&amp;quot;:&amp;quot;Austria&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;sunset&amp;quot;:&amp;quot;2013-08-09 20:40&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;rawOffset&amp;quot;:1,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;dstOffset&amp;quot;:2,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;countryCode&amp;quot;:&amp;quot;AT&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;gmtOffset&amp;quot;:1,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;lng&amp;quot;:10.2,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;sunrise&amp;quot;:&amp;quot;2013-08-09 06:07&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;timezoneId&amp;quot;:&amp;quot;Europe/Vienna&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;lat&amp;quot;:47.01&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
This API returns a bit more information. There is no limit to the number of calls you can make but the response times are not guaranteed. I used it for several thousand calls and had no problems.&lt;br /&gt;
&lt;br /&gt;
So now we have two different web calls we can use to get the timezone information. Let's look at how we can use Go to make the Google web call and get an object back that we can use in our program.&lt;br /&gt;
&lt;br /&gt;
First, we need to define a new type that can contain the information we will get back from the API.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;encoding/json&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;io/ioutil&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;net/http&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;time&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
const googleURI = &amp;quot;[https://maps.googleapis.com/maps/api/timezone/json?location=%f,%f&amp;amp;timestamp=%d&amp;amp;sensor=false](/broken-link) &amp;quot;&lt;br /&gt;
&lt;br /&gt;
type GoogleTimezone struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; DstOffset &amp;nbsp; &amp;nbsp;float64 `bson:&amp;quot;dstOffset&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; RawOffset &amp;nbsp; &amp;nbsp;float64 `bson:&amp;quot;rawOffset&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Status &amp;nbsp; &amp;nbsp; &amp;nbsp; string &amp;nbsp;`bson:&amp;quot;status&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; TimezoneID &amp;nbsp; string &amp;nbsp;`bson:&amp;quot;timeZoneId&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; TimezoneName string &amp;nbsp;`bson:&amp;quot;timeZoneName&amp;quot;`&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Go has awesome support for JSON and XML. If you look at the GoogleTimezone struct you will see that each field contains a &amp;quot;tag&amp;quot;. A tag is extra data attached to each field that can later be retrieved by our program using reflection. To learn more about tags read this document:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/pkg/reflect/#StructTag" target="_blank"&gt;http://golang.org/pkg/reflect/#StructTag&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The encoding/json package has defined a set of tags it looks for to help with marshaling and unmarshaling JSON data. To learn more about the JSON support in Go read these documents:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/doc/articles/json_and_go.html" target="_blank"&gt;http://golang.org/doc/articles/json_and_go.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://golang.org/pkg/encoding/json/" target="_blank"&gt;http://golang.org/pkg/encoding/json/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If you make the field names in your struct the same as the field names in the JSON document, you don't need to use the tags. I didn't do that so the tags are there to tell the Unmarshal function how to map the data.&lt;br /&gt;
&lt;br /&gt;
Let's look at a function that can make the API call to Google and unmarshal the JSON document to our new type:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func RetrieveGoogleTimezone(latitude float64, longitude float64) (googleTimezone &amp;#42;GoogleTimezone, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; uri := fmt.Sprintf(googleURI, latitude, longitude, time.Now().UTC().Unix())&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; resp, err := http.Get(uri)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer resp.Body.Close()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Convert the response to a byte array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; rawDocument, err = ioutil.ReadAll(resp.Body)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Unmarshal the response to a GoogleTimezone object&lt;br /&gt;
&amp;nbsp; &amp;nbsp; googleTimezone = new(GoogleTimezone)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err = json.Unmarshal(rawDocument, googleTimezone); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if googleTimezone.Status != &amp;quot;OK&amp;quot; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;Error : Google Status : %s&amp;quot;, googleTimezone.Status)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if len(googleTimezone.TimezoneId) == 0 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;Error : No Timezone Id Provided&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return googleTimezone, err&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The web call and error handling is fairly boilerplate so let's just talk briefly about the Unmarshal call.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;nbsp; &amp;nbsp; rawDocument, err = ioutil.ReadAll(resp.Body)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; err = json.Unmarshal(rawDocument, googleTimezone)&lt;/div&gt;
&lt;br /&gt;
When the web call returns, we take the response and store it in a byte array. Then we call the json Unmarshal function, passing the byte array and a reference to our return type pointer variable. The Unmarshal call creates an object of type GoogleTimezone, extracts and copies the data from the returned JSON document and sets the value of our pointer variable. It's really brilliant. If any fields can't be mapped they are simply ignored. The Unmarshal call will return an error if there are casting issues.&lt;br /&gt;
&lt;br /&gt;
So this is great, we can get the timezone data and unmarshal it to an object with three lines of code. Now the only problem is, how the heck do we use the timezoneid to set our location?&lt;br /&gt;
&lt;br /&gt;
Here is the problem again. We have to take the local time from the feed document, apply the timezone information and then convert everything UTC.&lt;br /&gt;
&lt;br /&gt;
Let's look at the feed document again:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&lt;b&gt;&amp;lt;timezone&amp;gt;LST/LDT&amp;lt;/timezone&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;item&amp;gt;&lt;br /&gt;
&lt;b&gt;&amp;lt;date&amp;gt;2013/01/01&amp;lt;/date&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;day&amp;gt;Tue&amp;lt;/day&amp;gt;&lt;br /&gt;
&lt;b&gt;&amp;lt;time&amp;gt;02:06 AM&amp;lt;/time&amp;gt;&lt;/b&gt;&lt;br /&gt;
&amp;lt;predictions_in_ft&amp;gt;19.7&amp;lt;/predictions_in_ft&amp;gt;&lt;br /&gt;
&amp;lt;predictions_in_cm&amp;gt;600&amp;lt;/predictions_in_cm&amp;gt;&lt;br /&gt;
&amp;lt;highlow&amp;gt;H&amp;lt;/highlow&amp;gt;&lt;br /&gt;
&amp;lt;/item&amp;gt;
&lt;/div&gt;
&lt;br /&gt;
Assuming we have extracted the data from this document, how can we use the timezoneid to get us out of this jam? Look at the code I wrote in the main function. It uses the time.LoadLocation function and the timezone id we get from the API call to solve the problem:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Call to get the timezone for this lat and lng position&lt;br /&gt;
&amp;nbsp; &amp;nbsp; googleTimezone, err := RetrieveGoogleTimezone(38.85682, -92.991714)
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;ERROR : %s&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Pretend this is the date and time we extracted&lt;br /&gt;
&amp;nbsp; &amp;nbsp; year := 2013&lt;br /&gt;
&amp;nbsp; &amp;nbsp; month := 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; day := 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; hour := 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; minute := 6&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; /&lt;b&gt;/ Capture the location based on the timezone id from Google&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; location, err := time.LoadLocation(googleTimezone.TimezoneId)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;ERROR : %s&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Capture the local and UTC time based on timezone&lt;br /&gt;
&amp;nbsp; &amp;nbsp; localTime := time.Date(year, time.Month(month), day, hour, minute, 0, 0, &lt;b&gt;location&lt;/b&gt;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; utcTime := localTime.UTC()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Display the results&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Timezone:\t%s\n&amp;quot;, googleTimezone.TimezoneId)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Local Time: %v\n&amp;quot;, localTime)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;UTC Time: %v\n&amp;quot;, utcTime)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Here is the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Timezone: &amp;nbsp; America/Chicago&lt;br /&gt;
Local Time: 2013-01-01 02:06:00 -0600 CST&lt;br /&gt;
Time: &amp;nbsp; &amp;nbsp; &amp;nbsp; 2013-01-01 08:06:00 +0000 UTC
&lt;/div&gt;
&lt;br /&gt;
Everything worked like a champ. Our localTime variable is set to CST or Central Standard Time, which is where Chicago is located. &amp;nbsp;The Google API provided the correct timezone for the latitude and longitude because that location falls within Missouri.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://maps.google.com/maps?q=39.232253,-92.991714&amp;amp;z=6" target="_blank"&gt;https://maps.google.com/maps?q=39.232253,-92.991714&amp;amp;z=6&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The last question we have to ask is how did the LoadLocation function take that timezone id string and make this work. The timezone id contains both a country and city (America/Chicago). There must be thousands of these timezone ids.&lt;br /&gt;
&lt;br /&gt;
If we take a look at the time package documentation for LoadLocation, we will find the answer:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/pkg/time/#LoadLocation" target="_blank"&gt;http://golang.org/pkg/time/#LoadLocation&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the documentation for LoadLocation:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
LoadLocation returns the Location with the given name.&lt;br /&gt;
&lt;br /&gt;
If the name is &amp;quot;&amp;quot; or &amp;quot;UTC&amp;quot;, LoadLocation returns UTC. If the name is &amp;quot;Local&amp;quot;, LoadLocation returns Local.&lt;br /&gt;
&lt;br /&gt;
Otherwise, the name is taken to be a location name corresponding to a file in the IANA Time Zone database, such as &amp;quot;America/New_York&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. LoadLocation looks in the directory or uncompressed zip file named by the ZONEINFO environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in $GOROOT/lib/time/zoneinfo.zip.
&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
If you read the last paragraph you will see that the LoadLocation function is reading a database file to get the information. I didn't download any database, nor did I set an environment variable called ZONEINFO. The only answer is that this zoneinfo.zip file exists in GOROOT. Let's take a look:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-08-08+at+8.06.04+PM.png)
&lt;/div&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
Sure enough there is a zoneinfo.zip file located in the lib/time directory where Go was installed. Very Cool !!&lt;br /&gt;
&lt;br /&gt;
There you have it. Now you know how to use the time.LoadLocation function to help make sure your time values are always in the correct timezone. If you have a latitude and longitude, you can use either API to get that timezone id.&lt;br /&gt;
&lt;br /&gt;
I have added a new package called timezone to the GoingGo repository in Github if you want a reusable copy of the code with both API calls. &amp;nbsp;Here is the entire working sample program:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;encoding/json&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;io/ioutil&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;net/http&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;time&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
const (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; googleURI = &amp;quot;[https://maps.googleapis.com/maps/api/timezone/json?location=%f,%f&amp;amp;timestamp=%d&amp;amp;sensor=false](/broken-link)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
type GoogleTimezone struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; DstOffset &amp;nbsp; &amp;nbsp;float64 `bson:&amp;quot;dstOffset&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; RawOffset &amp;nbsp; &amp;nbsp;float64 `bson:&amp;quot;rawOffset&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Status &amp;nbsp; &amp;nbsp; &amp;nbsp; string &amp;nbsp;`bson:&amp;quot;status&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; TimezoneID &amp;nbsp; string &amp;nbsp;`bson:&amp;quot;timeZoneId&amp;quot;`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; TimezoneName string &amp;nbsp;`bson:&amp;quot;timeZoneName&amp;quot;`&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Call to get the timezone for this lat and lng position&lt;br /&gt;
&amp;nbsp; &amp;nbsp; googleTimezone, err := RetrieveGoogleTimezone(38.85682, -92.991714)
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;ERROR : %s&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Pretend this is the date and time we extracted&lt;br /&gt;
&amp;nbsp; &amp;nbsp; year := 2013&lt;br /&gt;
&amp;nbsp; &amp;nbsp; month := 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; day := 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; hour := 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; minute := 6&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Capture the location based on the timezone id from Google&lt;br /&gt;
&amp;nbsp; &amp;nbsp; location, err := time.LoadLocation(googleTimezone.TimezoneID)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;ERROR : %s&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Capture the local and UTC time based on timezone&lt;br /&gt;
&amp;nbsp; &amp;nbsp; localTime := time.Date(year, time.Month(month), day, hour, minute, 0, 0, location)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; utcTime := localTime.UTC()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Display the results&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Timezone:\t%s\n&amp;quot;, googleTimezone.TimezoneID)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Local Time: %v\n&amp;quot;, localTime)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;UTC Time: %v\n&amp;quot;, utcTime)&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
func RetrieveGoogleTimezone(latitude float64, longitude float64) (googleTimezone &amp;#42;GoogleTimezone, err error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; uri := fmt.Sprintf(googleURI, latitude, longitude, time.Now().UTC().Unix())&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; resp, err := http.Get(uri)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer resp.Body.Close()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Convert the response to a byte array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; rawDocument, err := ioutil.ReadAll(resp.Body)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Unmarshal the response to a GoogleTimezone object&lt;br /&gt;
&amp;nbsp; &amp;nbsp; googleTimezone = new(GoogleTimezone)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err = json.Unmarshal(rawDocument, &amp;amp;googleTimezone); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if googleTimezone.Status != &amp;quot;OK&amp;quot; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;Error : Google Status : %s&amp;quot;, googleTimezone.Status)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if len(googleTimezone.TimezoneID) == 0 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;Error : No Timezone Id Provided&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&amp;nbsp;googleTimezone, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return googleTimezone, err&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;</description></item><item><title>Gustavo's IEEE-754 Brain Teaser</title><link>https://www.ardanlabs.com/blog/2013/08/gustavos-ieee-754-brain-teaser.html</link><pubDate>Mon, 05 Aug 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/08/gustavos-ieee-754-brain-teaser.html</guid><description>&lt;p&gt;Back in June, Gustavo Niemeyer posted the following question on his &lt;a href="http://blog.labix.org/" target="_blank"&gt;Labix.org&lt;/a&gt; blog:&lt;br /&gt;&lt;/p&gt;
&lt;br /&gt;
&lt;i&gt;Assume uf is an unsigned integer with 64 bits that holds the IEEE-754 representation for a binary floating point number of that size.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;How can you tell if uf represents an integer number?&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
I can't talk for you, but I write business applications. I just don't have the background to quickly knock out an answer for a question like this. Fortunately Gustavo posted the logic for the answer. I thought it would be fun to better understand the question and break down his answer. I am going to work with a 32 bit number just to make everything easier.&lt;br /&gt;
&lt;br /&gt;
How does the IEEE-754 standard store a floating point number in a binary format? &amp;nbsp;To start I found these two pages:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://steve.hollasch.net/cgindex/coding/ieeefloat.html" target="_blank"&gt;http://steve.hollasch.net/cgindex/coding/ieeefloat.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html" target="_blank"&gt;http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The IEEE-754 specification represents a floating point number in base 2 scientific notation using a special binary format. If you don't know what I mean by base 2 then look at my post on Understanding Type In Go (&lt;a href="https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html" target="_blank"&gt;https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Scientific notation is an efficient way of writing very large or small numbers. It works by using a decimal format with a multiplier. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Base 10 Number&lt;/th&gt;
 &lt;th&gt;Scientific Notation&lt;/th&gt;
 &lt;th&gt;Calculation&lt;/th&gt;
 &lt;th&gt;Coefficient&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Base&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Exponent&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Mantissa&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody class="table-striped"&gt;
 &lt;tr&gt;
 &lt;td&gt;700&lt;/td&gt;
 &lt;td&gt;7e+2&lt;/td&gt;
 &lt;td&gt;7 &amp;#42; 10&lt;sup&gt;2&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;7&lt;/td&gt;&lt;td style="text-align:center"&gt;10&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;4,900,000,000&lt;/td&gt;
 &lt;td&gt;4.9e+9&lt;/td&gt;
 &lt;td&gt;4.9 &amp;#42; 10&lt;sup&gt;9&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;4.9&lt;/td&gt;
 &lt;td style="text-align:center"&gt;10&lt;/td&gt;
 &lt;td style="text-align:center"&gt;9&lt;/td&gt;
 &lt;td style="text-align:center"&gt;.9&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;5362.63&lt;/td&gt;
 &lt;td&gt;5.36263e+3&lt;/td&gt;
 &lt;td&gt;5.36263 &amp;#42; 10&lt;sup&gt;3&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;5.36263&lt;/td&gt;
 &lt;td style="text-align:center"&gt;10&lt;/td&gt;
 &lt;td style="text-align:center"&gt;3&lt;/td&gt;
 &lt;td style="text-align:center"&gt;.36263&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;-0.00345&lt;/td&gt;
 &lt;td&gt;3.45e-3&lt;/td&gt;
 &lt;td&gt;3.45 &amp;#42; 10&lt;sup&gt;-3&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;3.45&lt;/td&gt;
 &lt;td style="text-align:center"&gt;10&lt;/td&gt;
 &lt;td style="text-align:center"&gt;-3&lt;/td&gt;
 &lt;td style="text-align:center"&gt;.45&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;0.085&lt;/td&gt;
 &lt;td&gt;1.36e-4&lt;/td&gt;
 &lt;td&gt;1.36 &amp;#42; 2&lt;sup&gt;-4&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;1.36&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;/td&gt;
 &lt;td style="text-align:center"&gt;-4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;.36&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
In normal scientific notation form there is always just one digit on the left side of the decimal point. For base 10 numbers that digit must be between 1 through 9 and for base 2 numbers that digit can only be 1.&lt;br /&gt;
&lt;br /&gt;
The entire number in scientific notation is called the Coefficient.&amp;nbsp;The Mantissa is all the numbers to the right of the decimal point. These terms are important so take the time to study and understand the chart above.&lt;br /&gt;
&lt;br /&gt;
How we move the decimal point to that first position determines the value of the Exponent. If we have to move the decimal point to the left, the Exponent is a positive number, to the right, it is a negative number. Look at the chart above and see the Exponent value for each example.&lt;br /&gt;
&lt;br /&gt;
The Base and the Exponent work together in the notation. The exponent determines the &amp;quot;Power Of&amp;quot; calculation we need to perform on the base. In the first example the number 7 is multiplied by 10 (The Base) to the power of 2 (The Exponent) to get back to the original base 10 number 700. We moved the decimal point to the left two places to convert 700 to 7.00, which made the Exponent +2 and created the notation of 7e+2.&lt;br /&gt;
&lt;br /&gt;
The IEEE-754 standard does not store base 10 scientific notation numbers but base 2 scientific notation numbers. The last example in the chart above represents the base 10 number 0.085 in base 2 scientific notation. Let's learn how that notation is calculated.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Base 10 Number&lt;/th&gt;
 &lt;th&gt;Scientific Notation&lt;/th&gt;
 &lt;th&gt;Calculation&lt;/th&gt;
 &lt;th&gt;Coefficient&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Base&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Exponent&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Mantissa&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;0.085&lt;/td&gt;
 &lt;td&gt;1.36e-4&lt;/td&gt;
 &lt;td&gt;1.36 &amp;#42; 2&lt;sup&gt;-4&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;1.36&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;/td&gt;
 &lt;td style="text-align:center"&gt;-4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;.36&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
We need to divide the base 10 number (0.085) by some power of two so we get a 1 + Fraction value. What do I mean by a 1 + Fraction value? We need a number that looks like the Coefficient in the example, 1 + .36. The IEEE-754 standard requires that we have a &amp;quot;1.&amp;quot; in the Coefficient. This allows us to only have to store the Mantissa and give us an extra bit of precision.&lt;br /&gt;
&lt;br /&gt;
If we use brute force you will see when we finally get the 1 + Fraction value for 0.085:&lt;br /&gt;
&lt;br /&gt;
0.085 / 2&lt;sup&gt;-1&lt;/sup&gt; = 0.17&lt;br /&gt;
0.085 / 2&lt;sup&gt;-2&lt;/sup&gt; = 0.34&lt;br /&gt;
0.085 / 2&lt;sup&gt;-3&lt;/sup&gt; = 0.68&lt;br /&gt;
0.085 / 2&lt;sup&gt;-4&lt;/sup&gt; = 1.36 &amp;nbsp; &amp;#42;&amp;#42; We found the 1 + Fraction&lt;br /&gt;
&lt;br /&gt;
An exponent of -4 gives us the 1 + Fraction value we need. Now we have everything we need to store the base 10 number 0.085 in IEEE-754 format.&lt;br /&gt;
&lt;br /&gt;
Let's look at how the bits are laid out in the IEEE-754 format.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Precision&lt;/th&gt;
 &lt;th&gt;Sign&lt;/th&gt;
 &lt;th&gt;Exponent&lt;/th&gt;
 &lt;th&gt;Fraction Bits&lt;/th&gt;
 &lt;th&gt;Bias&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Single (32 Bits)&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1 [31]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;8 [30-23]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;23 [22-00]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;127&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Double (64 Bits)&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1 [63]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;11 [62-52]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;52 [51-00]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1023&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
The bits are broken into three parts. There is a bit reserved for the sign, bits for the exponent and bits that are called fraction bits. The fractions bits are where we store the mantissa as a binary fraction.&lt;br /&gt;
&lt;br /&gt;
If we store the value of 0.085 using Single Precision (a 32 bit number), the bit pattern in IEEE-754 would look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Sign&lt;/th&gt;
 &lt;th&gt;Exponent (123)&lt;/th&gt;
 &lt;th&gt;Fraction Bits (.36)&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;0&lt;/td&gt;
 &lt;td&gt;0111 1011&lt;/td&gt;
 &lt;td&gt;010 1110 0001 0100 0111 1011&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
The Sign bit, the leftmost bit, determines if the number is positive or negative. If the bit is set to 1 then the number is negative else it is positive.&lt;br /&gt;
&lt;br /&gt;
The next 8 bits represent the Exponent. In our example, the base 10 number 0.085 is converted to 1.36 &amp;#42; 2&lt;sup&gt;-4&lt;/sup&gt;&amp;nbsp;using base 2 scientific notation. Therefore the value of the exponent is -4. In order to be able to represent negative numbers, there is a Bias value. The Bias value for our 32 bit representation is 127. To represent the number -4, we need to find the number, that when subtract against the Bias, gives us -4. In our case that number is 123. If you look at the bit pattern for the Exponent you will see it represents the number 123 in binary.&lt;br /&gt;
&lt;br /&gt;
The remaining 23 bits are the Fraction bits. To calculate the bit pattern for the fraction bits, we need to calculate and sum binary fractions until we get the value of the Mantissa, or a value that is as close as possible. Remember, we only need to store the Mantissa because we always assume that the &amp;quot;1.&amp;quot; value exists.&lt;br /&gt;
&lt;br /&gt;
To understand how binary fractions are calculated, look at the following chart. Each bit position from left to right represents a fractional value:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Binary&lt;/th&gt;
 &lt;th&gt;Fraction&lt;/th&gt;
 &lt;th&gt;Decimal&lt;/th&gt;
 &lt;th&gt;Power&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;0.1&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/2&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.5&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;sup&gt;-1&lt;/sup&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;0.01&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.25&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;sup&gt;-2&lt;/sup&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;0.001&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/8&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.125&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2&lt;sup&gt;-3&lt;/sup&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
We need to set the correct number of fraction bits that add up to or gets us close enough to the mantissa. This is why we can sometimes lose precision.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;td align="center" colspan="5"&gt;0&lt;b&gt;1&lt;/b&gt;0&amp;nbsp;&lt;b&gt;111&lt;/b&gt;0 000&lt;b&gt;1&lt;/b&gt;&amp;nbsp;0&lt;b&gt;1&lt;/b&gt;00 0&lt;b&gt;111&lt;/b&gt;&amp;nbsp;&lt;b&gt;1&lt;/b&gt;0&lt;b&gt;11&lt;/b&gt;&amp;nbsp;= (0.36)&lt;/td&gt;
 &lt;tr&gt;
 &lt;th style="text-align:center"&gt;Bit&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Value&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Fraction&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Decimal&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Total&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;2&lt;/td&gt;
 &lt;td style="text-align:center"&gt;4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.25&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.25&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;4&lt;/td&gt;
 &lt;td style="text-align:center"&gt;16&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/16&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.0625&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.3125&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;5&lt;/td&gt;
 &lt;td style="text-align:center"&gt;32&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/32&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.03125&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.34375&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;6&lt;/td&gt;
 &lt;td style="text-align:center"&gt;64&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/64&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.015625&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.359375&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;11&lt;/td&gt;
 &lt;td style="text-align:center"&gt;2048&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/2048&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00048828125&lt;/td&gt;
 &lt;td align="right"&gt;0.35986328125&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;13&lt;/td&gt;
 &lt;td style="text-align:center"&gt;8192&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/8192&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.0001220703125&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.3599853515625&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;17&lt;/td&gt;
 &lt;td style="text-align:center"&gt;131072&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/131072&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000762939453&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.35999298095703&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;18&lt;/td&gt;
 &lt;td style="text-align:center"&gt;262144&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/262144&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000381469727&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.3599967956543&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;19&lt;/td&gt;
 &lt;td style="text-align:center"&gt;524288&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/524288&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000190734863&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.35999870300293&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;20&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1048576&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/1048576&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000095367432&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.35999965667725&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;22&lt;/td&gt;
 &lt;td style="text-align:center"&gt;4194304&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/4194304&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000023841858&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.35999989509583&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;23&lt;/td&gt;
 &lt;td style="text-align:center"&gt;8388608&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1/8388608&lt;/td&gt;
 &lt;td style="text-align:center"&gt;0.00000011920929&lt;/td&gt;
 &lt;td style="text-align:right"&gt;0.36000001430512&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
You can see that setting these 12 bits get us to the value of 0.36 plus some extra fractions.&lt;br /&gt;
&lt;br /&gt;
Let's sum up what we now know about the IEEE-754 format:&lt;br /&gt;
&lt;br /&gt;
1. Any base 10 number to be stored is converted to base 2 scientific notation.&lt;br /&gt;
2. The base 2 scientific notation value we use must follow the 1 + Fraction format.&lt;br /&gt;
3. There are three distinct sections in the format.&lt;br /&gt;
4. The Sign bit determines if the number is positive or negative.&lt;br /&gt;
5. The Exponent bits represent a number that needs to be subtracted against the Bias.&lt;br /&gt;
6. The Fraction bits represent the Mantissa using binary fraction summation.&lt;br /&gt;
&lt;br /&gt;
Let's prove that our analysis is correct about the IEEE-754 format. We should be able to store the number 0.85 and display bit patterns and values for each section that match everything we have seen.&lt;br /&gt;
&lt;br /&gt;
The following code stores the number 0.085 and displays the IEEE-754 binary representation:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;math&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var number float32 = 0.085&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Starting Number: %f\n\n&amp;quot;, number)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Float32bits returns the IEEE 754 binary representation&lt;br /&gt;
&amp;nbsp; &amp;nbsp; bits := math.Float32bits(number)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; binary := fmt.Sprintf(&amp;quot;%.32b&amp;quot;, bits)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Bit Pattern: %s | %s %s | %s %s %s %s %s %s\n\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[0:1],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[1:5], binary[5:9],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[9:12], binary[12:16], binary[16:20],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[20:24], binary[24:28], binary[28:32])&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; bias := 127&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sign := bits &amp;amp; (1 &amp;lt;&amp;lt; 31)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponentRaw := int(bits &amp;gt;&amp;gt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponent := exponentRaw - bias&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var mantissa float64&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for index, bit := range binary[9:32] {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if bit == 49 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; position := index + 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bitValue := math.Pow(2, float64(position))&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fractional := 1 / bitValue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mantissa = mantissa + fractional&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value := (1 + mantissa) &amp;#42; math.Pow(2, float64(exponent))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Sign: %d Exponent: %d (%d) Mantissa: %f Value: %f\n\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sign,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponentRaw,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponent,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mantissa,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; value)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
When we run the program we get the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Starting Number: 0.085000&lt;br /&gt;
&lt;br /&gt;
Bit Pattern: 0 | 0111 1011 | 010 1110 0001 0100 0111 1011&lt;br /&gt;
&lt;br /&gt;
Sign: 0 Exponent: 123 (-4) Mantissa: 0.360000 Value: 0.085000
&lt;/div&gt;
&lt;br /&gt;
If you compare the displayed bit pattern with our example above, you will see that it matches. Everything we learned about IEEE-754 is true.&lt;br /&gt;
&lt;br /&gt;
Now we should be able to answer Gustavo's question. How can we tell if the value being stored is an integer? Here is a function, thanks to Gustavo's code, that tests if the IEEE-754 stored value is an integer:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func IsInt(bits uint32, bias int) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponent := int(bits &amp;gt;&amp;gt; 23) - bias - 23&lt;br /&gt;
&amp;nbsp; &amp;nbsp; coefficient&amp;nbsp;:= (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1)) | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; intTest := (coefficient&amp;nbsp;&amp;amp; (1 &amp;lt;&amp;lt; uint32(-exponent) - 1))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;\nExponent: %d Coefficient: %d IntTest: %d\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponent,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; coefficient,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; intTest)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if exponent &amp;lt; -23 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;NOT INTEGER\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if exponent &amp;lt; 0 &amp;amp;&amp;amp; intTest != 0 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;NOT INTEGER\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;INTEGER\n&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
So how does this function work?&lt;br /&gt;
&lt;br /&gt;
Let's start with the first condition which tests if the Exponent is less than -23. If we use the number 1 as our test number, the exponent will be 127 which is the same as the Bias. This means when we subtract the Exponent against the Bias we will get zero.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Starting Number: &lt;b&gt;1.000000&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Bit Pattern: 0 | 0111 1111 | 000 0000 0000 0000 0000 0000&lt;br /&gt;
&lt;br /&gt;
Sign: 0 Exponent: &lt;b&gt;127 (0)&lt;/b&gt; Mantissa: 0.000000 Value: 1.000000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Exponent: &lt;b&gt;-23&lt;/b&gt; Coefficient: 8388608 IntTest: 0&lt;br /&gt;
INTEGER
&lt;/div&gt;
&lt;br /&gt;
The test function adds an extra subtraction of 23, which represents the starting bit position for the Exponent in the IEEE-754 format. That is why you see -23 for the Exponent value coming from the test function.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="table-responsive"&gt;
 &lt;table class="table table-bordered table-striped"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align:center"&gt;Precision&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Sign&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Exponent&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Fraction Bits&lt;/th&gt;
 &lt;th style="text-align:center"&gt;Bias&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align:center"&gt;Single (32 Bits)&lt;/td&gt;
 &lt;td style="text-align:center"&gt;1 [31]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;8 [30-&lt;b&gt;23&lt;/b&gt;]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;23 [22-00]&lt;/td&gt;
 &lt;td style="text-align:center"&gt;127&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
This subtraction is required to help with the second test. So any value that is less than -23 must be less than one (1) and therefore not an integer.&lt;br /&gt;
&lt;br /&gt;
To understand how the second test works, let's use an integer value. This time we will set the number to 234523 in the code and run the program again.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Starting Number: 234523.000000&lt;br /&gt;
&lt;br /&gt;
Bit Pattern: 0 | 1001 0000 | 110 0101 0000 0110 1100 0000&lt;br /&gt;
&lt;br /&gt;
Sign: 0 Exponent: 144 (17) Mantissa: 0.789268 Value: 234523.000000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Exponent:&amp;nbsp;-6&amp;nbsp;Coefficient: 15009472 IntTest: 0&lt;br /&gt;
INTEGER&lt;/div&gt;
&lt;br /&gt;
The second test looks for two conditions to identify if the number is not an integer. This requires the use of bitwise mathematics. Let's look at the math we are performing in the function:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;nbsp; &amp;nbsp; exponent := int(bits &amp;gt;&amp;gt; 23) - bias - 23&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;coefficient&amp;nbsp;:= (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1)) | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; intTest := coefficient&amp;nbsp;&amp;amp; ((1 &amp;lt;&amp;lt; uint32(-exponent)) - 1)&lt;/div&gt;
&lt;br /&gt;
The coefficient calculation is adding the 1 + to the Mantissa so we have the base 2 Coefficient value.&lt;br /&gt;
&lt;br /&gt;
When we look at the first part of the coefficient calculation we see the following bit patterns:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
coefficient := &lt;b&gt;(bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1))&lt;/b&gt; | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&lt;br /&gt;
Bits: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;010010000&lt;/b&gt;11001010000011011000000&lt;br /&gt;
(1 &amp;lt;&amp;lt; 23) - 1: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00000000011111111111111111111111&lt;br /&gt;
bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1): &lt;b&gt;000000000&lt;/b&gt;11001010000011011000000
&lt;/div&gt;
&lt;br /&gt;
The first part of the coefficient calculation removes the bits for the Sign and Exponent from the entire IEEE-754 bit pattern.&lt;br /&gt;
&lt;br /&gt;
The second part of the coefficient&amp;nbsp;calculation&amp;nbsp;adds the &amp;quot;1 +&amp;quot; into the binary bit pattern:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
coefficient := (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1)) | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&lt;br /&gt;
bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1): 00000000&lt;b&gt;0&lt;/b&gt;11001010000011011000000&lt;br /&gt;
(1 &amp;lt;&amp;lt; 23): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00000000&lt;b&gt;1&lt;/b&gt;00000000000000000000000&lt;br /&gt;
coefficient: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00000000&lt;b&gt;1&lt;/b&gt;11001010000011011000000&lt;/div&gt;
&lt;br /&gt;
Now that the coefficient bit pattern is set, we can calculate the intTest value:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
exponent := int(bits &amp;gt;&amp;gt; 23) - bias - 23&lt;br /&gt;
intTest := (coefficient&amp;nbsp;&amp;amp; ((1 &amp;lt;&amp;lt; uint32(-exponent)) - 1))&lt;br /&gt;
&lt;br /&gt;
exponent: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (144 - 127 - 23) = -6&lt;br /&gt;
1 &amp;lt;&amp;lt; uint32(-exponent): &amp;nbsp; &amp;nbsp; &amp;nbsp; 000000&lt;br /&gt;
(1 &amp;lt;&amp;lt; uint32(-exponent)) - 1: 111111&lt;br /&gt;
&lt;br /&gt;
coefficient: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 00000000111001010000011011&lt;b&gt;000000&lt;/b&gt;&lt;br /&gt;
1 &amp;lt;&amp;lt; uint32(-exponent)) - 1: 00000000000000000000000000&lt;b&gt;111111&lt;/b&gt;&lt;br /&gt;
intTest: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 00000000000000000000000000&lt;b&gt;000000&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
The value of the exponent we calculate in the test function is used to determine the number of bits we will compare against the Coefficient. In this case the exponent value is -6. That is calculated by subtracting the stored Exponent value (144) against the Bias (127) and then against the starting bit position for the Exponent (23). This gives us a bit pattern of 6 ones (1's). The final operation takes those 6 bits and AND's them against the rightmost 6 bits of the Coefficient to get the intTest value.&lt;br /&gt;
&lt;br /&gt;
The second test is looking for an exponent value that is less than zero (0) and an intTest value that is NOT zero (0). This would indicate the number being stored is not an integer. In our example with 234523, the Exponent is less than zero (0), but the value of intTest is zero (0). We have an integer.&lt;br /&gt;
&lt;br /&gt;
I have included the sample code in the Go playground so you can play with it.&lt;br /&gt;
&lt;br /&gt;
[http://play.golang.org/p/3xraud43pi](/broken-link)
&lt;br /&gt;
&lt;br /&gt;
If it wasn't for Gustavo's code I could never have identified the solution. Here is a link to his solution:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://bazaar.launchpad.net/~niemeyer/strepr/trunk/view/6/strepr.go#L160" target="_blank"&gt;http://bazaar.launchpad.net/~niemeyer/strepr/trunk/view/6/strepr.go#L160&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a copy of the code that you can copy and paste:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #253443; color: #bababa; font-family: monospace; font-size: 13px; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;math&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var number float32 = 234523&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Starting Number: %f\n\n&amp;quot;, number)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Float32bits returns the IEEE 754 binary representation&lt;br /&gt;
&amp;nbsp; &amp;nbsp; bits := math.Float32bits(number)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; binary := fmt.Sprintf(&amp;quot;%.32b&amp;quot;, bits)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Bit Pattern: %s | %s %s | %s %s %s %s %s %s\n\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[0:1],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[1:5], binary[5:9],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[9:12], binary[12:16], binary[16:20],&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; binary[20:24], binary[24:28], binary[28:32])&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; bias := 127&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sign := bits &amp;amp; (1 &amp;lt;&amp;lt; 31)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponentRaw := int(bits &amp;gt;&amp;gt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponent := exponentRaw - bias&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var mantissa float64&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for index, bit := range binary[9:32] {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if bit == 49 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; position := index + 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bitValue := math.Pow(2, float64(position))&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fractional := 1 / bitValue&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mantissa = mantissa + fractional&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value := (1 + mantissa) &amp;#42; math.Pow(2, float64(exponent))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Sign: %d Exponent: %d (%d) Mantissa: %f Value: %f\n\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sign,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponentRaw,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponent,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mantissa,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; value)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IsInt(bits, bias)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func IsInt(bits uint32, bias int) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; exponent := int(bits&amp;gt;&amp;gt;23) - bias - 23&lt;br /&gt;
&amp;nbsp; &amp;nbsp; coefficient := (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1)) | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; intTest := coefficient &amp;amp; ((1 &amp;lt;&amp;lt; uint32(-exponent)) - 1)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ShowBits(bits, bias, exponent)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;\nExp: %d Frac: %d IntTest: %d\n&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exponent,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; coefficient,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; intTest)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if exponent &amp;lt; -23 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;NOT INTEGER\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if exponent &amp;lt; 0 &amp;amp;&amp;amp; intTest != 0 {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;NOT INTEGER\n&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;INTEGER\n&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func ShowBits(bits uint32, bias int, exponent int) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value := (1 &amp;lt;&amp;lt; 23) - 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value2 := (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1))&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value3 := (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; coefficient := (bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1)) | (1 &amp;lt;&amp;lt; 23)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Bits:\t\t\t%.32b\n&amp;quot;, bits)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;(1 &amp;lt;&amp;lt; 23) - 1:\t\t%.32b\n&amp;quot;, value)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1):\t\t%.32b\n\n&amp;quot;, value2)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;bits &amp;amp; ((1 &amp;lt;&amp;lt; 23) - 1):\t\t%.32b\n&amp;quot;, value2)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;(1 &amp;lt;&amp;lt; 23):\t\t\t%.32b\n&amp;quot;, value3)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;coefficient:\t\t\t%.32b\n\n&amp;quot;, coefficient)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value5 := 1 &amp;lt;&amp;lt; uint32(-exponent)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; value6 := (1 &amp;lt;&amp;lt; uint32(-exponent)) - 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; inTest := (coefficient &amp;amp; ((1 &amp;lt;&amp;lt; uint32(-exponent)) - 1))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;1 &amp;lt;&amp;lt; uint32(-exponent):\t\t%.32b\n&amp;quot;, value5)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;(1 &amp;lt;&amp;lt; uint32(-exponent)) - 1:\t%.32b\n\n&amp;quot;, value6)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;coefficient:\t\t\t%.32b\n&amp;quot;, coefficient)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;(1 &amp;lt;&amp;lt; uint32(-exponent)) - 1:\t%.32b\n&amp;quot;, value6)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;intTest:\t\t\t%.32b\n&amp;quot;, inTest)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
I want to thank Gustavo for posting the question and giving me something to really fight through to understand.</description></item><item><title>An RSS Feed Searching Framework Using Go</title><link>https://www.ardanlabs.com/blog/2013/07/an-rss-feed-searching-framework-using-go.html</link><pubDate>Mon, 29 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/an-rss-feed-searching-framework-using-go.html</guid><description>&lt;p&gt;This article was written for and published by Safari Books Online
&lt;br /&gt;
&lt;br /&gt;
Back in May, I finally decided that it was time to move away from the Microsoft stack to Linux. The cost of developing, licensing, and purchasing cloud computing on the Microsoft stack is too expensive. My company was approved for BizSpark, which made development possible for a small company like mine, but what am I going to do three years from now? My other problem is how can I ask a client to pay thousands of dollars for Microsoft cloud computing and licensing, especially when the open source technologies that run on Linux only cost hundreds of dollars, and those technologies scale better.
&lt;br /&gt;
&lt;br /&gt;
We have been using Ruby for some time now for our web projects. Unfortunately, we have needed to stay on .NET for our server development. I didn’t want to start writing C/C++ again and Ruby, Erlang and every other language I looked at just didn’t feel right for this type of development. Then my partner told me to look at Go.&lt;br /&gt;
&lt;br /&gt;
You can implement very robust code using the Go programming language and paradigms. In a few hours I was able to write a program called NewsSearch. The program downloads a list of RSS feed documents and processes them using different search plugins. The first search plugin is called Expression. It searches through each RSS document looking for matching keywords or regular expressions. It displays any matching documents and where the match was made.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://www.ardanlabs.com/broken-link"&gt;Continue reading →&lt;/a&gt;&lt;/p&gt;</description></item><item><title>An Open Source Debate</title><link>https://www.ardanlabs.com/blog/2013/07/an-open-source-debate.html</link><pubDate>Sat, 27 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/an-open-source-debate.html</guid><description>&lt;p&gt;&lt;i&gt;This article was written for and published by Safari Books Online&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
If you read my article titled Analyze Data With MongoDB and Go, then you will understand the context of this debate with the idea of open source. That article talks about an application we are building, and it publishes some of the proprietary data we are gathering. It also shows techniques we are using to perform the data analysis. This has caused a passionate debate among the business partners in my company. Does the article provide too much proprietary information that could harm our success with the application?
&lt;br /&gt;
&lt;br /&gt;
Let me go back in time for a bit. When Microsoft released .NET to the world back in 2003, I was quick to leave C++ programming behind. I began to port all of my C++ utilities, so I could write Windows services in C#. During this time, I wrote two articles about my thread pooling and socket utilities. They were published and I was excited, but I was quickly told to stop because I was crazy for giving away all of this code.&lt;/p&gt;</description></item><item><title>Understanding Pointers and Memory Allocation</title><link>https://www.ardanlabs.com/blog/2013/07/understanding-pointers-and-memory.html</link><pubDate>Sat, 27 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/understanding-pointers-and-memory.html</guid><description>&lt;p&gt;In the documentation provided by the Go language team you will find great information on pointers and memory allocation. Here is a link to that documentation:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/doc/faq#Pointers"&gt;&lt;a href="http://golang.org/doc/faq#Pointers"&gt;http://golang.org/doc/faq#Pointers&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
We need to start with the understanding that all variables contain a value. Based on the type that variable represents will determine how we can use it to manipulate the memory it contains. Read this post to learn more: &lt;a href="https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html"&gt;Understanding Type In Go&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Analyze Data With MongoDB and Go</title><link>https://www.ardanlabs.com/blog/2013/07/analyze-data-with-mongodb-and-go.html</link><pubDate>Wed, 24 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/analyze-data-with-mongodb-and-go.html</guid><description>&lt;p&gt;&lt;i&gt;This article was written for and published by Safari Books Online&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
My company is building a mobile application called Outcast. The idea behind Outcast is to give people who love the outdoors the ability to get ahead of the weather. By analyzing real time buoy, tide, lunar and solar data with user preferences and experiences, the application can deliver relevant information and forecasts. The user helps with the forecasting by providing an experience review after their outdoor activities have ended. Over time, the application learns what is the best condition for each individual user, their activity and favorite locations.&lt;br /&gt;&lt;/p&gt;</description></item><item><title>OSCON 2013 - The Gophers Are Coming</title><link>https://www.ardanlabs.com/blog/2013/07/oscon-2013-gophers-are-coming.html</link><pubDate>Sat, 20 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/oscon-2013-gophers-are-coming.html</guid><description>&lt;p&gt;On June 22nd through the 26th, Portland Oregon is hosting OSCON (Open Source Convention). The event is run by O&amp;rsquo;Reilly. After looking at the speakers list it appears it is going to be a great convention.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;There are three Gophers who will be giving talks. Check out the links:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Francesc Campoy Flores &lt;/b&gt;&lt;br /&gt;
Go Developer Programs Engineer, Google Inc.&lt;br /&gt;
&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/155088" target="_blank"&gt;&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/155088"&gt;http://www.oscon.com/oscon2013/public/schedule/speaker/155088&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Johan Euphrosine&lt;/b&gt;&lt;br /&gt;
Developer Programs Engineer, Google&lt;br /&gt;
&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/155083" target="_blank"&gt;&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/155083"&gt;http://www.oscon.com/oscon2013/public/schedule/speaker/155083&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Brad Fitzpatrick&lt;/b&gt;&lt;br /&gt;
Software Engineer, Google&lt;br /&gt;
&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/25905" target="_blank"&gt;&lt;a href="http://www.oscon.com/oscon2013/public/schedule/speaker/25905"&gt;http://www.oscon.com/oscon2013/public/schedule/speaker/25905&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I have also been asked by &lt;a href="http://www.backstopmedia.com/" target="_blank"&gt;Backstop Media&lt;/a&gt; to write a few article on Go to supplement the conference. Once they are publish I will provide links and a quick summary.&lt;br /&gt;
&lt;br /&gt;
If you are going to the convention have a great time. I can&amp;rsquo;t wait to see the content and videos that come out of it.&lt;/p&gt;</description></item><item><title>Understanding Type in Go</title><link>https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html</link><pubDate>Fri, 12 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html</guid><description>&lt;p&gt;When I was coding in C/C++ it was imperative to understand type. If you didn&amp;rsquo;t, you would get into a lot of trouble with both the compiler and running your code. Regardless of the language, type touches every aspect of programming syntax. A good understand of types and pointers is critical to good programming. This post will focus on type.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Take these bytes of memory for starters:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Object Oriented Programming in Go</title><link>https://www.ardanlabs.com/blog/2013/07/object-oriented-programming-in-go.html</link><pubDate>Wed, 10 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/object-oriented-programming-in-go.html</guid><description>&lt;p&gt;Someone asked a question on the forum today on how to gain the benefits of inheritance without embedding. It is really important for everyone to think in terms of Go and not the languages they are leaving behind. I can&amp;rsquo;t tell you much code I removed from my early Go implementations because it wasn&amp;rsquo;t necessary. The language designers have years of experience and knowledge. Hindsight is helping to create a language that is fast, lean and really fun to code in.&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Singleton Design Pattern in Go</title><link>https://www.ardanlabs.com/blog/2013/07/singleton-design-pattern-in-go.html</link><pubDate>Sat, 06 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/singleton-design-pattern-in-go.html</guid><description>&lt;p&gt;Multi-threaded applications are very complicated, especially when your code is not organized and consistent with how resources are accessed, managed and maintained. If you want to minimize bugs you need philosophies and rules to live by. Here are some of mine:&lt;br /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Resource allocation and de-allocation should be abstracted and managed within the same type.&lt;/li&gt;
&lt;li&gt;Resource thread safeness should be abstracted and managed within the same type.&lt;/li&gt;
&lt;li&gt;A public interface should be the only means to accessing shared resources.&lt;/li&gt;
&lt;li&gt;Any thread that allocates a resource should de-allocated the same resource.&lt;/li&gt;
&lt;/ol&gt;
In Go we don't have threads but Go Routines. The Go runtime abstracts the threading and task swapping of these routines. Regardless, the same philosophies and rules apply.&lt;br /&gt;
&lt;br /&gt;
One of my favorite design patterns is the Singleton. It provides a great implementation when&amp;nbsp;you only need one instance of a type and that type manages shared resources. A Singleton is a design pattern where the type creates an instance of itself and keeps that reference private. Access to the shared resources managed by that reference is abstracted through a static pubic interface. These static methods also provide thread safeness. The application using the Singleton is responsible for initializing and de-initializing the Singleton but never has direct access to the internals.&lt;br /&gt;
&lt;br /&gt;
It escaped me for some time how to implement a Singleton in Go because Go is not a traditional object oriented programming language and there are no static methods.&lt;br /&gt;
&lt;br /&gt;
I consider Go to be a light object oriented programming language. Yes it does have encapsulation and type member functions but it lacks&amp;nbsp;inheritance&amp;nbsp;and therefore traditional polymorphism. In all of the OOP languages I have ever used, I never used inheritance unless I wanted to implement polymorphism. With the way interfaces are implemented in Go there is no need for&amp;nbsp;inheritance.&amp;nbsp;Go took the best parts of OOP, left out the rest and gave us a better way to write polymorphic code.&lt;br /&gt;
&lt;br /&gt;
In Go we can implement a Singleton by leveraging the scoping and encapsulation rules of packages and types. For this post we will explore my straps package since it will give us a real world example.
&lt;br /&gt;
&lt;br /&gt;
The straps package provides a mechanism to store configuration options (straps) in an XML document and read them into memory for use by the application. The name strap comes from the early days of configuring networking equipment. Those settings were called straps and that name has always stuck with me. In the MacOS we have .plist files, in .Net we have app.config files and in Go I have straps.xml files.
&lt;br /&gt;
&lt;br /&gt;
Here is a sample straps files for one of my applications:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;lt;straps&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;!-- Log Settings --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;baseFilePath&amp;quot; value=&amp;quot;/Users/bill/Logs/OC-DataServer&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;machineName&amp;quot; value=&amp;quot;my-machine&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;daysToKeep&amp;quot; value=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;!-- ServerManager Settings --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;cpuMultiplier&amp;quot; value=&amp;quot;100&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/straps&amp;gt;
&lt;/div&gt;
&lt;br /&gt;
The straps package knows how to read this xml file and provide access to the values via a Singleton based public interface. Since these values only need to be read into memory once a Singleton is a great option for this package.&lt;br /&gt;
&lt;br /&gt;
Here is the package and type information for straps:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package straps&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;encoding/xml&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;io&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;path/filepath&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;strconv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
.&lt;br /&gt;
. Types Removed&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
type straps struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; StrapMap map[string]string // The map of strap key value pairs&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var st straps // A reference to the singleton
&lt;/div&gt;
&lt;br /&gt;
I am not going to talk about the aspects of reading the XML document. If you are interested please read this blog post&amp;nbsp;&lt;a href="https://www.ardanlabs.com/blog/2013/06/reading-xml-documents-in-go.html"&gt;https://www.ardanlabs.com/blog/2013/06/reading-xml-documents-in-go.html&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
In the code&amp;nbsp;snippet above you will see the package name (straps), the definition of the private type &lt;i&gt;straps&lt;/i&gt; and the private package variable &lt;i&gt;st&lt;/i&gt;. The &lt;i&gt;st&lt;/i&gt; variable will contain the value for the Singleton.&lt;br /&gt;
&lt;br /&gt;
The scoping rules for Go state that types and functions that start with a capital letter are public and accessible outside of the package. Types and functions that start with a lowercase letter are private and not accessible outside of the package.&lt;br /&gt;
&lt;br /&gt;
I name my variables that are defined within the scope of a function with lowercase letters. Variable names defined outside the scope of a function, such as type members and package variables start with a capital letter. This allows me to look at the code and know instantly where memory for any given variable is being referenced.&lt;br /&gt;
&lt;br /&gt;
Both the &lt;i&gt;straps&lt;/i&gt; type and the &lt;i&gt;st&lt;/i&gt; variable are private and only accessible from within the package.&lt;br /&gt;
&lt;br /&gt;
Look at the Load function which initializes the Singleton for use:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func MustLoad() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Find the location of the straps.xml file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; strapsFilePath, err := filepath.Abs(&amp;quot;straps.xml&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Open the straps.xml file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; file, err := os.Open(strapsFilePath)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; panic(err.Error())&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer file.Close()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Read the straps file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; xmlStraps, err := readStraps(file)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; panic(err.Error())&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;// Create a straps object&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; st = straps{&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; StrapMap: make(map[string]string),&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Store the key/value pairs for each strap&lt;br /&gt;
&amp;nbsp; &amp;nbsp; for _, strap := range xmlStraps {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; st.StrapMap[strap.Key] = strap.Value&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The Load function is a public function of the package. Applications can access this function through the package name. You can see how I use names that start with a lowercase letter for local variables. At the bottom of the Load function a straps object is created and the reference is set to the &lt;i&gt;st&lt;/i&gt; variable. At this point the Singleton exists and straps is ready to use.&lt;br /&gt;
&lt;br /&gt;
Accessing the straps is done with the public function Strap:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func Strap(key string) string {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return st.StrapMap[key]&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
The public function Strap uses the Singleton reference to access the shared resource. In this case the map of straps. If the map could change during the lifetime of the application, then a mutex or some other synchronization object would need to be used to protect the map.&amp;nbsp;Luckily&amp;nbsp;the straps never change once they are loaded.&lt;br /&gt;
&lt;br /&gt;
Since the resource being managed by straps is just memory there is no need for an Unload or Close method. If we needed a function to close any resources another public function would have to be created.&lt;br /&gt;
&lt;br /&gt;
If private methods are required in the Singleton package to help organize code, I like to use member functions. Since the type is private I can make the member functions public because they won't be accessible. I also think the member functions help make the code more readable. By looking to see if the function is a member function or not I know if the function is private or part of the public interface.&lt;br /&gt;
&lt;br /&gt;
Here is a example of using a member function:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func SomePublicFunction() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; .&lt;br /&gt;
&amp;nbsp; &amp;nbsp; st.SomePrivateMemberFunction(&amp;quot;key&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; .&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (straps &amp;#42;straps) SomePrivateMemberFunction(key string) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return straps.StrapMap[key]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; .&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Since the function is a member function we need to use the &lt;i&gt;st&lt;/i&gt; variable to make the function call. From within the member function I use the local variable (straps) and not the &lt;i&gt;st&lt;/i&gt; variable. The member function is public but the reference is private so only the package can reference the member function. This is just a convention I established for myself.&lt;br /&gt;
&lt;br /&gt;
Here is a sample program that uses the straps package:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;ArdanStudios/straps&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; straps.MustLoad()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; cpu := straps.Strap(&amp;quot;cpuMultiplier&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
In main we don't need to allocate any memory or maintain references. Through the package name we call Load to initialize the Singleton. Then through the package name again we access the public interface, in this case the Strap function.&lt;br /&gt;
&lt;br /&gt;
If you have the same need to managed shared resources through a public interface try using a Singleton.&lt;br /&gt;
&lt;br /&gt;
As always I hope this helps you write better and bug less code.</description></item><item><title>How Packages Work in Go</title><link>https://www.ardanlabs.com/blog/2013/07/how-packages-work-in-go-language.html</link><pubDate>Fri, 05 Jul 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/07/how-packages-work-in-go-language.html</guid><description>&lt;p&gt;Since I started writing code in Go it has been a mystery to me how best to organize my code and use the package keyword. The package keyword is similar to using a namespace in C#, however the convention is to tie the package name to the directory structure.&lt;br /&gt;&lt;/p&gt;
&lt;br /&gt;
Go has this web page that attempts to explain how to write Go Code.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/doc/code.html"&gt;http://golang.org/doc/code.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
When I started programming in Go this was one of the first documents I read. This went way over my head, mainly because I have been working in Visual Studio and code is packaged for you in Solution and Project files. Working out of a directory on the file system was a crazy thought. &amp;nbsp;Now I love the simplicity of it but it has taken quite a while for it all to make sense.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;How to Write Go Code&amp;quot; starts out with the concept of a Workspace. Think of this as the root directory for your project. If you were working in Visual Studio this is where the solution or project file would be located. Then from inside your Workspace you need to create a single sub-directory called src. This is mandatory if you want the Go tools to work properly. From within the src directory you have the freedom to organize your code the way you want. However you need to understand the conventions set forth by the Go team for packages and source code or you could be refactoring your code down the line.&lt;br /&gt;
&lt;br /&gt;
On my machine I created a Workspace called Test and the required sub-directory called src. This is the first step in creating your project.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.03.44+AM.png)
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="clear: both;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear:left; float:left; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.10.42+AM.png)
&lt;/div&gt;
&lt;br /&gt;
Then in LiteIDE open the Test directory (the Workspace), and create the following sub-directories and empty Go source code files.&lt;br /&gt;
&lt;br /&gt;
First we create a sub-directory for the application we are creating. The name of the directory where the main function is located will be the name of the executable. In our case main.go contains the main function and is under the myprogram directory. This means our executable file will be called myprogram.&lt;br /&gt;
&lt;br /&gt;
The other sub-directories inside of src will contain packages for our project. By convention the name of the directory should be the name of the&amp;nbsp;package for those source code files that are located in that directory. In our case the new packages are called samplepkg and subpkg. The name of the source code files can be anything you like.&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear:left; float:left; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.07.09+AM.png)
&lt;/div&gt;
&lt;br /&gt;
Create the same package folders and empty Go source code files to follow along.&lt;br /&gt;
&lt;br /&gt;
If you don't add the Workspace folder to the GOPATH we will have problems.&lt;br /&gt;
&lt;br /&gt;
It took me a bit to realize that the Custom Directories window is a Text Box. So you can edit those folders directly. The System GOPATH is read only.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
The Go designers have done several things when naming their packages and source code files. All the file names and directories are lowercase and they did not use underscores to break words apart in the package directory names. Also, the package names match the directory names. Code files within a directory belong to a package named after the directory.&lt;br /&gt;
&lt;br /&gt;
Take a look at the Go source code directory for a few of the standard library packages:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear:left; float:left; margin-bottom:1em; margin-right:1em; width:400px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.09.25+AM.png)
&lt;/div&gt;
&lt;br /&gt;
The package directories for bufio and builtin are great examples of the directory naming convention. They could have been called buf_io and built_in.&lt;br /&gt;
&lt;br /&gt;
Look again at the Go source code directory and review the names of the source code files.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: right; float: right; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.17.49+AM.png)
&lt;/div&gt;
&lt;br /&gt;
Notice the use of the underscore in some of the file names. When the file contains test code or is specific to a particular platform, an underscore is used.&lt;br /&gt;
&lt;br /&gt;
The usual convention is to name one of the source code files the same as the package name. In bufio this convention is followed. However, this is a&amp;nbsp;loosely&amp;nbsp;followed convention.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: left; float: left; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.20.36+AM.png)
&lt;/div&gt;
&lt;br /&gt;
In the fmt package you will notice there is no source code file named fmt.go. I&amp;nbsp;personally&amp;nbsp;like naming my packages and source code files differently.&lt;br /&gt;
&lt;br /&gt;
Last, open the doc.go, format.go, print.go and scan.go files. They are all declared to be in the fmt package.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
Let's take a look at the code for sample.go:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package samplepkg&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
type Sample struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Name string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func New(name string) (sample &amp;#42; Sample) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return &amp;amp;Sample{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: name,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (sample &amp;#42; Sample) Print() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Sample Name:&amp;quot;, sample.Name)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The code is useless but it will let us focus on the two important conventions. First, notice the name of the package is the same as the name of the sub-directory. Second, there is a function called New.&lt;br /&gt;
&lt;br /&gt;
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&lt;b&gt;log.go&lt;/b&gt;&lt;br /&gt;
// New creates a new Logger. The out variable sets the&lt;br /&gt;
// destination to which log data will be written.&lt;br /&gt;
// The prefix appears at the beginning of each generated log line.&lt;br /&gt;
// The flag argument defines the logging properties.&lt;br /&gt;
func New(out io.Writer, prefix string, flag int) &amp;#42; Logger {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return &amp;amp;Logger{out: out, prefix: prefix, flag: flag}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;bufio.go&lt;/b&gt;&lt;br /&gt;
// NewReader returns a new Reader whose buffer has the default size.&lt;br /&gt;
func NewReader(rd io.Reader) &amp;#42; Reader {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return NewReaderSize(rd, defaultBufSize)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;crypto.go&lt;/b&gt;&lt;br /&gt;
// New returns a new hash.Hash calculating the given hash function. New panics&lt;br /&gt;
// if the hash function is not linked into the binary.&lt;br /&gt;
func (h Hash) New() hash.Hash {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if h &amp;gt; 0 &amp;amp;&amp;amp; h &amp;lt; maxHash {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; f := hashes[h]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if f != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return f()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; panic(&amp;quot;crypto: requested hash function is unavailable&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.&lt;br /&gt;
&lt;br /&gt;
Look back at sample.go. In our code the core type is Sample, so our New function returns a reference to a Sample type. Then we added a member function to display the name we provided in New.&lt;br /&gt;
&lt;br /&gt;
Now let's look at the code for sub.go:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package subpkg&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
type Sub struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Name string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func New(name string) (sub &amp;#42; Sub) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return &amp;amp;Sub{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Name: name,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func (sub &amp;#42; Sub) Print() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Sub Name:&amp;quot;, sub.Name)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
The code is identical except we named our core type Sub. The package name matches the sub-directory name and New returns a reference to a Sub type.&lt;br /&gt;
&lt;br /&gt;
Now that our packages are properly defined and coded we can use them.&lt;br /&gt;
&lt;br /&gt;
Look at the code for main.go:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;samplepkg&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;samplepkg/subpkg&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sample := samplepkg.New(&amp;quot;Test Sample Package&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sample.Print()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sub := subpkg.New(&amp;quot;Test Sub Package&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; sub.Print()&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Since our GOPATH points to the Workspace directory, in my case /Users/bill/Spaces/Test, our import references start from that point. Here we are referencing both packages based on the directory structure.&lt;br /&gt;
&lt;br /&gt;
Next we call the New functions for each respective package and create variables of those core types.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: left; float: left; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.23.25+AM.png)
&lt;/div&gt;
&lt;br /&gt;
Now build and run the program. You should see that an executable program was created called myprogram.&lt;br /&gt;
&lt;br /&gt;
Once your program is ready for distribution you can run the install command.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: right; float: right; margin-bottom:1em; margin-right:1em; width:320px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2013-07-28+at+10.24.16+AM.png)
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The install command will create the bin and pkg folders in your Workspace. Notice the final executable was placed under the bin directory.&lt;br /&gt;
&lt;br /&gt;
The compiled packages were placed under the pkg directory. Within that directory a sub-directory that describes the target&amp;nbsp;architecture is created and that mirrors the source directories.&lt;br /&gt;
&lt;br /&gt;
These compiled packages exist so the go tool can avoid recompiling the source code unnecessarily.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
The problem with that last statement, found in the &amp;quot;How to Write Go Code&amp;quot; post, is that these .a files are ignore by the Go tool when performing future builds of your code. Without the source code files you can't build your program. I have not found any documentation to really explain how these .a files can be used directly to build Go programs. If anyone can shed some light on this topic it would be greatly appreciated.&lt;br /&gt;
&lt;br /&gt;
At the end of the day it is best to follow the conventions handled down from the Go designers. Looking at the source code they have written provides the best documentation for how to do things. Many of us are writing code for the community. If we all follow the same conventions we can be&amp;nbsp;assured of compatibility and readability.&amp;nbsp;When in doubt open finder to /usr/local/go/src/pkg and start digging.&lt;br /&gt;
&lt;br /&gt;
As always I hope this helps you understand the Go programming&amp;nbsp;language a little better.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Running Go Programs as a Background Process</title><link>https://www.ardanlabs.com/blog/2013/06/running-go-programs-as-background.html</link><pubDate>Mon, 24 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/running-go-programs-as-background.html</guid><description>&lt;p&gt;I have been writing Windows services in C/C++ and then in C# since 1999. Now that I am writing server based software in Go for the Linux OS I am completely lost. What is even more frustrating, is that for the first time the OS I am developing on (Mac OSX) is not the operating system I will be deploying my code on. That will be for another blog post.&lt;/p&gt;</description></item><item><title>Reading XML Documents in Go</title><link>https://www.ardanlabs.com/blog/2013/06/reading-xml-documents-in-go.html</link><pubDate>Mon, 17 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/reading-xml-documents-in-go.html</guid><description>&lt;p&gt;I was really surprised how easy it was to read an XML document using the encoding/xml package that comes with the standard library. The package works by defining structs that map the XML document. If you need more flexibility then use Gustavo Niemeyer&amp;rsquo;s xmlpath package (&lt;a href="http://godoc.org/launchpad.net/xmlpath" target="_blank"&gt;found here)&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here is the XML document we are going to read and de-serialize:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;lt;straps&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;CompanyName&amp;quot; value=&amp;quot;NEWCO&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;UseEmail&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/straps&amp;gt;&lt;/div&gt;
&lt;br /&gt;
The first thing we need to do is define the structs we will use to map the document:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type XMLStrap struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; XMLName &amp;nbsp;xml.Name &amp;#768; xml:&amp;quot;strap&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Key &amp;nbsp; &amp;nbsp; &amp;nbsp;string &amp;nbsp; &amp;#768; xml:&amp;quot;key,attr&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Value &amp;nbsp; &amp;nbsp;string &amp;nbsp; &amp;#768; xml:&amp;quot;value,attr&amp;quot;&amp;#768; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
type XMLStraps struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; XMLName &amp;nbsp;xml.Name &amp;nbsp; &amp;nbsp;&amp;#768; xml:&amp;quot;straps&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Straps &amp;nbsp; []XMLStrap &amp;#768; xml:&amp;quot;strap&amp;quot;&amp;#768; &lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
There are two structs, one for the entire document (&amp;lt;straps&amp;gt;) and one for each individual child node (&amp;lt;strap&amp;gt;). If you look closely at the structs you may see something new. Each field has a tag associated with it. These tags are bound to each individual field. Go's reflect package allows you to access these tags.&lt;br /&gt;
&lt;br /&gt;
These tag formats are specific to the decoding support inside the encoding/xml&amp;nbsp;package. The tags map the nodes and attributes of the XML document to the struct.&lt;br /&gt;
&lt;br /&gt;
The following code decodes the XML document and returns the array of strap nodes:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var xmlStraps XMLStraps&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err :=&amp;nbsp;xml.NewDecoder(reader).Decode(&amp;amp;xmlStraps); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return nil, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return xmlStraps.Straps, nil&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The function takes an io.Reader. We will be passing a os.File variable into this method. The function returns an array of pointers for each strap we read from the file.&lt;br /&gt;
&lt;br /&gt;
First we create a XMLStraps variable and get its address. Next we create a decoder using the xml.NewDecoder method passing the io.Reader object. Then we call Decode which reads the file and de-serializes the file into the XMLStraps variable. Then we just return the array of strap values.&lt;br /&gt;
&lt;br /&gt;
The following completes the sample code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
/&amp;#42;&lt;br /&gt;
straps.xml should be located in the default working directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;straps&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;CompanyName&amp;quot; value=&amp;quot;NEWCO&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;strap key=&amp;quot;UseEmail&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/straps&amp;gt;&lt;br /&gt;
&amp;#42;/&lt;br /&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;encoding/xml&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;io&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;os&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;path/filepath&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
type XMLStrap struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; XMLName &amp;nbsp;xml.Name &amp;#768; xml:&amp;quot;strap&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Key &amp;nbsp; &amp;nbsp; &amp;nbsp;string &amp;nbsp; &amp;#768; xml:&amp;quot;key,attr&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Value &amp;nbsp; &amp;nbsp;string &amp;nbsp; &amp;#768; xml:&amp;quot;value,attr&amp;quot;&amp;#768; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
type XMLStraps struct {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; XMLName &amp;nbsp;xml.Name &amp;nbsp; &amp;nbsp;&amp;#768; xml:&amp;quot;straps&amp;quot;&amp;#768; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Straps &amp;nbsp; []XMLStrap &amp;#768; xml:&amp;quot;strap&amp;quot;&amp;#768; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; var xmlStraps XMLStraps&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err :=&amp;nbsp;xml.NewDecoder(reader).Decode(&amp;amp;xmlStraps); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return nil, err&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; return xmlStraps.Straps, nil&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Build the location of the straps.xml file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // filepath.Abs appends the file name to the default working directly&lt;br /&gt;
&amp;nbsp; &amp;nbsp; strapsFilePath, err := filepath.Abs(&amp;quot;straps.xml&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.Exit(1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Open the straps.xml file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; file, err := os.Open(strapsFilePath)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.Exit(1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; defer file.Close()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Read the straps file&lt;br /&gt;
&amp;nbsp; &amp;nbsp; xmlStraps, err := ReadStraps(file)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.Exit(1)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; // Display The first strap&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Key: %s &amp;nbsp;Value: %s&amp;quot;,&amp;nbsp;xmlStraps[0].Key,&amp;nbsp;xmlStraps[0].Value)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
I hope this sample gets you started with reading XML documents for your Go applications.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Send an email in Go with smtp.SendMail</title><link>https://www.ardanlabs.com/blog/2013/06/send-email-in-go-with-smtpsendmail.html</link><pubDate>Thu, 13 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/send-email-in-go-with-smtpsendmail.html</guid><description>&lt;p&gt;I wanted to send an email from my TraceLog package when a critical exception occurred. Fortunately Go&amp;rsquo;s standard library has a package called smpt which can be found inside the net package. When you look at the documentation you are left wanting.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;I spent 20 minutes researching how to use this package. After fighting through the parameters and bugs, I came up with this sample code:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Go's time.Duration Type Unravelled</title><link>https://www.ardanlabs.com/blog/2013/06/gos-duration-type-unravelled.html</link><pubDate>Tue, 11 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/gos-duration-type-unravelled.html</guid><description>&lt;p&gt;I have been struggling with using the Time package that comes in the Go standard library. My struggles have come from two pieces of functionality. First, trying to capture the number of milliseconds between two different time periods. Second, comparing that duration in milliseconds against a pre-defined time span. It sounds like a no brainier but like I said, I have been struggling.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;In the Time package there is a custom type called Duration and a set of helper constants:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Understanding Defer, Panic and Recover</title><link>https://www.ardanlabs.com/blog/2013/06/understanding-defer-panic-and-recover.html</link><pubDate>Sat, 08 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/understanding-defer-panic-and-recover.html</guid><description>&lt;p&gt;I am building my TraceLog package and it is really important that the package logs any internal exceptions and prevents panics from shutting down the application. The TraceLog package must never be responsible for shutting down an application. I also have internal go routines that must never terminate until the application is shut down gracefully.&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
Understanding how to use Defer and Recover in your application can be a bit tricky at first, especially if you are used to using try/catch blocks. There is a pattern you can implement to provide that same type of try/catch protection in Go. Before I can show you this you need to learn how Defer, Panic and Recover work.&lt;br /&gt;
&lt;br /&gt;
First you need to understand the&amp;nbsp;intricacies&amp;nbsp;of the keyword defer. Start with this piece of code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; test()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func mimicError(key string) &lt;b&gt;error&lt;/b&gt; {&lt;br /&gt;
&amp;nbsp; return fmt.Errorf(&amp;quot;Mimic Error : %s&amp;quot;, key)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func test() { &lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;err&lt;/b&gt; := mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;defer&lt;/b&gt; func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; if &lt;b&gt;err&lt;/b&gt; != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, &lt;b&gt;err&lt;/b&gt;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;End Test&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The MimicError function is a test function that will be used to simulate an error. It is following the Go convention of using the&amp;nbsp;error&amp;nbsp;type to return an indication if something went wrong.&lt;br /&gt;
&lt;br /&gt;
In Go the error type is defined as an interface:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
type error interface {&lt;br /&gt;
&amp;nbsp; Error() string&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
If you don't understand what a Go interface is at the moment then this might help for now. Any type that implements the &lt;b&gt;&lt;i&gt;Error()&lt;/i&gt;&lt;/b&gt; function implements this interface and can be used as a variable of this type. The MimicError function is using &lt;b&gt;&lt;i&gt;errors.New(string)&lt;/i&gt;&lt;/b&gt;&amp;nbsp;to create an&amp;nbsp;error type variable. The errors type can be found in the errors package.&lt;br /&gt;
&lt;br /&gt;
Test&amp;nbsp;function produces the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
End Test&lt;br /&gt;
Start Defer&lt;br /&gt;
Defer Error : Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
When you study the output you see that the Test function started and ended. Then right before the Test function terminated for good, the inline defer function was called. Two interesting things are happening here. First, the defer keyword is deferring the execution of the inline function until the Test function ends. Second, because Go supports closure, the err variable is accessible to the inline function and its message &amp;quot;Mimic Error : 1&amp;quot; is written to stdout.&lt;br /&gt;
&lt;br /&gt;
You can define a defer function at any time inside your function. If that defer function requires state, as in this case with the err variable, then it must exist before the defer function is defined.&lt;br /&gt;
&lt;br /&gt;
Now change the Test function a bit:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() {&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;err := mimicError(&amp;quot;1&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if &lt;b&gt;err&lt;/b&gt; != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, &lt;b&gt;err&lt;/b&gt;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;err = mimicError(&amp;quot;2&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;End Test&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
This time the code is calling the MimicError function a second time after creating the inline defer function. Here is the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
End Test&lt;br /&gt;
Start Defer&lt;br /&gt;
Defer Error : Mimic Error : &lt;b&gt;2
&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
The output is identical from the first test except for one change. This time the inline defer function wrote &amp;quot;Mimic Error : 2&amp;quot;. It appears that the inline defer function has a reference to the err variable. So if the state of the err variable changes at any time before the inline defer function is called, you will see that value. To verify that the inline defer function is getting a reference to the err variable, change the code to write the address of the err variable in both the Test function and the inline defer function.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() {&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err := mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;fmt.&lt;/b&gt;&amp;nbsp;Println&lt;b&gt;(&amp;quot;Err Addr:&amp;quot;, &amp;amp;err)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;fmt.&lt;/b&gt;Println&lt;b&gt;(&amp;quot;Err Addr Defer:&amp;quot;, &amp;amp;err)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;End Test&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
As you can see from the output below, the inline defer function has the same reference to the err variable. The address is the same inside of the Test function and inside of the inline defer function.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Err Addr: &lt;b&gt;0x2101b3200&lt;/b&gt;&lt;br /&gt;
End Test&lt;br /&gt;
Start Defer&lt;br /&gt;
Err Addr Defer: &lt;b&gt;0x2101b3200&lt;/b&gt;&lt;br /&gt;
Defer Error : Mimic Error : 2
&lt;/div&gt;
&lt;br /&gt;
As long as the defer function is stated before the Test function terminates, the defer function will be executed. This is great, but what I want is the ability to always place the defer statement at the beginning of any function. This way the defer function is&amp;nbsp;guaranteed&amp;nbsp;to be called&amp;nbsp;every time&amp;nbsp;the function is executed and I don't have to over think where to place the defer statement. Occam's Razor applies here:&amp;nbsp;&lt;b&gt;&amp;quot;When you have two competing theories that make exactly the same predictions, &lt;u&gt;the simpler one is the better&lt;/u&gt;&amp;quot;&lt;/b&gt;. What I want is an easy pattern that can be duplicated without requiring any thought.&lt;br /&gt;
&lt;br /&gt;
The only problem is that the err variable needs to be defined before the defer statement can be implemented. Fortunately Go allows return variables to have names.&lt;br /&gt;
&lt;br /&gt;
Now change the entire program as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; if err := test(); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Main Error: %v\n&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func mimicError(key string) error {&lt;br /&gt;
&amp;nbsp; return fmt.Errorf(&amp;quot;Mimic Error : %s&amp;quot;, key)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func test() &lt;b&gt;(err&amp;nbsp;error)&lt;/b&gt;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if &lt;b&gt;err&lt;/b&gt; != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, &lt;b&gt;err&lt;/b&gt;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;err&lt;/b&gt; = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;End Test&amp;quot;)&lt;br /&gt;
&amp;nbsp; return &lt;b&gt;err&lt;/b&gt;&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The Test function now defines a return variable called err of type error. This is great because the err variable exists immediately and you can put the defer statement at the very beginning of the function. Also, the Test function now follows the Go convention and returns an error type back to the calling routine.&lt;br /&gt;
&lt;br /&gt;
When you run the program you get the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
End Test&lt;br /&gt;
Start Defer&lt;br /&gt;
Defer Error : Mimic Error : 1&lt;br /&gt;
Main Error: Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
Now it is time to talk about the built-in function&amp;nbsp;&lt;b&gt;panic&lt;/b&gt;. When any Go function calls panic the normal flow of the application stops. The function that calls panic ends immediately and causes a chain reaction of panics up the call stack. All the functions in the same call stack will end, one after the next, like dominos falling down.&amp;nbsp;Eventually&amp;nbsp;the panic reaches the top of the call stack and the application crashes. One good thing is that any existing defer functions will be executed during this panic sequence and they have the ability to stop the crash.&lt;br /&gt;
&lt;br /&gt;
Look at this new Test function that calls the built in panic function and recovers from the call:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() error {&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Panic Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;if r := recover(); r != nil {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Panic:&amp;quot;, r)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;b&gt;panic(&amp;quot;Mimic Panic&amp;quot;)&lt;/b&gt;&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Look closely at the new inline defer function:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Panic Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;if r := recover(); r != nil {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Panic:&amp;quot;, r)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; }()&lt;/div&gt;
&lt;br /&gt;
The inline defer function is now calling another built-in function &lt;b&gt;recover&lt;/b&gt;. The recover function stops the chain reaction from going any farther up the call stack. It is like&amp;nbsp;swiping&amp;nbsp;a domino away so no more can fall down. The recover function can only be used inside of a defer function. This is because during the panic chain reaction only defer functions will be executed.&lt;br /&gt;
&lt;br /&gt;
If the recover function is called and there is no panic occurring, the recover function will return nil. If there is a panic occurring, then the panic is stopped and the value given to the panic call will be returned.&lt;br /&gt;
&lt;br /&gt;
This time the code is not calling the MimicError function but the built in panic function to simulate a panic. Look at the output from running the code:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Start Panic Defer&lt;br /&gt;
Defer Panic : Mimic Panic
&lt;/div&gt;
&lt;br /&gt;
The inline defer function captures the panic, prints it to the screen and stops it dead in its tracks. Also notice that &amp;quot;End Test&amp;quot; is never displayed. The function terminated as soon as panic was called.&lt;br /&gt;
&lt;br /&gt;
This is great but if there is an error I still want to display that as well. Something cool about Go and the defer keyword is that you can have more than one defer function stated at a time.&lt;br /&gt;
&lt;br /&gt;
Change the Test function as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() (err error) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;b&gt;defer func()&lt;/b&gt; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Panic Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Panic :&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;b&gt;defer func()&lt;/b&gt; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; panic(&amp;quot;Mimic Panic&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Now both inline defer functions have been incorporated into beginning of the Test function. First the inline defer function that that recovers from panics and then the inline defer function that prints errors. One thing to note is that Go will execute these inline defer functions in the opposite order that are defined (First In - Last Out).&lt;br /&gt;
&lt;br /&gt;
Run the code and look at the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Start Error Defer&lt;br /&gt;
Defer Error : Mimic Error : 1&lt;br /&gt;
Start Panic Defer&lt;br /&gt;
Defer Panic : Mimic Panic&lt;br /&gt;
Main Error: Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
The Test function starts as expected and the call to panic halts the execution of the Test function. This causes the inline defer function that prints errors to get called first. Since the Test function called the MimicError function before the panic, the error is printed. Then the inline defer function that recovers from panics is called and the panic is recovered.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;There is one problem with this code&lt;/b&gt;. The main function had no idea that a panic was averted. All the main function knows is that an error occurred thanks to the MimicError function call. This is not good. I want the main function to know about the error that caused the panic. That is really the error that must be reported.&lt;br /&gt;
&lt;br /&gt;
In the inline defer function that handles the panic we need to assign the error that caused the panic to the err variable.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() (err error) {&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Panic Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;Defer Panic : %v\n&amp;quot;, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; defer func() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Start Defer&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Defer Error:&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }()&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; panic(&amp;quot;Mimic Panic&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Now when you run the code you get the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Start Error Defer&lt;br /&gt;
Defer Error : Mimic Error : 1&lt;br /&gt;
Start Panic Defer&lt;br /&gt;
Defer Panic : Mimic Panic&lt;br /&gt;
&lt;b&gt;Main Error: Mimic Panic
&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
This time when main function reports the error that caused the panic.&lt;br /&gt;
&lt;br /&gt;
Everything looks good but this code is not really scalable. Having two inline defer functions is cool but not&amp;nbsp;practical. What I need is a single function that can handle both errors and panics.&lt;br /&gt;
&lt;br /&gt;
Here is a revised version of the full program with a new function called _CatchPanic:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; if err := test(); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Main Error:&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;func catchPanic(err error, functionName string) {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; if r := recover(); r != nil {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; if err != nil {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; } else&amp;nbsp;&lt;/b&gt;&lt;b&gt;if err != nil {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : ERROR : %v\n&amp;quot;, functionName, err)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;}
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
func mimicError(key string) error {&lt;br /&gt;
&amp;nbsp; return fmt.Errorf(&amp;quot;Mimic Error : %s&amp;quot;, key)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func test() (err error) {&lt;br /&gt;
&amp;nbsp; &lt;b&gt;defer catchPanic(err, &amp;quot;Test&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;End Test&amp;quot;)&lt;br /&gt;
&amp;nbsp; return err&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The new function _CatchPanic&amp;nbsp;incorporates both the panic recover and error handling. This time instead of defining an inline defer function the code is using an external function for the defer statement.&lt;br /&gt;
&lt;br /&gt;
In this first test with the new _CatchPanic defer function, we need to make sure we didn't break our error handling.&lt;br /&gt;
&lt;br /&gt;
Run the code and look at the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
End Test&lt;br /&gt;
Main Error: Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
Everything looks good. Now we need to test a panic.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func test() (err error) {&lt;br /&gt;
&amp;nbsp; &lt;b&gt;defer catchPanic(err, &amp;quot;Test&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&amp;nbsp; panic(&amp;quot;Mimic Panic&amp;quot;)&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Run the code and look at the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Test5 : PANIC Defered : Mimic Panic&lt;br /&gt;
Main Error: Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Houston we have a problem&lt;/b&gt;. &amp;nbsp;Main was provided the error from the MimicError function call and not from the panic. What went wrong?&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func catchPanic(err error, functionName string) {&lt;br /&gt;
&amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; } else if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : ERROR : %v\n&amp;quot;, functionName, err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Because defer is now calling an external function the code lost all the goodness that came with inline functions and Closure.&lt;br /&gt;
&lt;br /&gt;
Change the code to print the address of the err variable from inside the Test function and_CatchPanic defer function.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func _CatchPanic(err error, functionName string) {&lt;br /&gt;
&amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;fmt.Println(&amp;quot;Err Addr Defer:&amp;quot;, &amp;amp;err)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; } else if err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : ERROR : %v\n&amp;quot;, functionName, err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
func test() (err error) {&lt;br /&gt;
&amp;nbsp; &lt;b&gt;fmt.Println(&amp;quot;Err Addr:&amp;quot;, &amp;amp;err)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; defer _CatchPanic(err, &amp;quot;Test7&amp;quot;)&lt;br /&gt;
&amp;nbsp; fmt.Printf(&amp;quot;Start Test\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; panic(&amp;quot;Mimic Panic&amp;quot;)
&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
When you run the code you can see why main did not get the error from the panic.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Err Addr: &lt;b&gt;0x2101b31f0&lt;/b&gt;&lt;br /&gt;
Start Test&lt;br /&gt;
Test5 : PANIC Defered : Mimic Panic&lt;br /&gt;
Err Addr Defer: &lt;b&gt;0x2101b3270&lt;/b&gt;&lt;br /&gt;
Main Error: Mimic Error : 1
&lt;/div&gt;
&lt;br /&gt;
When the Test function passes the err variable to the catchPanic defer function it is passing the variable by value. In Go all arguments are passed by value. So the catchPanic defer function has its own copy of the err variable. Any changes to catchPanic's copy remains with catchPanic.&lt;br /&gt;
&lt;br /&gt;
To fix the pass by value problem the code needs to pass the err variable by reference.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
package main&lt;br /&gt;
&lt;br /&gt;
import (&lt;br /&gt;
&amp;nbsp; &amp;quot;fmt&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
func main() {&lt;br /&gt;
&amp;nbsp; if err := testFinal(); err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Println(&amp;quot;Main Error:&amp;quot;, err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func catchPanic(&lt;b&gt;err &amp;#42;error&lt;/b&gt;, functionName string) {&lt;br /&gt;
&amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;#42;err&lt;/b&gt; = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; } else if err != nil &amp;amp;&amp;amp;&amp;nbsp;&lt;b&gt;&amp;#42;err&lt;/b&gt; != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : ERROR : %v\n&amp;quot;, functionName, &lt;b&gt;&amp;#42;err&lt;/b&gt;)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
func mimicError(key string) error {&lt;br /&gt;
&amp;nbsp; return fmt.Errorf(&amp;quot;Mimic Error : %s&amp;quot;, key)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
func testFinal() (err error) {&lt;br /&gt;
&amp;nbsp; &lt;b&gt;defer catchPanic(&amp;amp;err, &amp;quot;TestFinal&amp;quot;)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; fmt.Println(&amp;quot;Start Test&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; err = mimicError(&amp;quot;1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; panic(&amp;quot;Mimic Panic&amp;quot;)&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
Now run the code and look at the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
Start Test&lt;br /&gt;
Test6 : PANIC Defered : Mimic Panic&lt;br /&gt;
Main Error: Mimic Panic
&lt;/div&gt;
&lt;br /&gt;
The main function now reports the error that occurred because of the panic.&lt;br /&gt;
&lt;br /&gt;
If you want to capture a stack trace as well just make this change to catchPanic. Remember to import &amp;quot;runtime&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func catchPanic(err &amp;#42;error, functionName string) {&lt;br /&gt;
&amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;// Capture the stack trace&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; buf := make([]byte, 10000)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; runtime.Stack(buf, false)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;%s : Stack Trace : %s&amp;quot;, functionName, string(buf))
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&amp;#42;err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; } else if err != nil &amp;amp;&amp;amp;&amp;nbsp;&amp;#42;err != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : ERROR : %v\n&amp;quot;, functionName, &amp;#42;err)&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
With this pattern you can implement Go routines that can handle errors and trap panic situations. In many cases these conditions just need to be logged or reported up the call stack to be handled gracefully. Having a single place to implement this type of code and a simple way to integrate it into each function will reduce errors and keep your code clean.&lt;br /&gt;
&lt;br /&gt;
However I have learned it is best to only use this pattern to catch panics only. Leave the logging of errors to the application logic. If not then you may be logging the errors twice.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;"&gt;
func catchPanic(err &amp;#42;error, functionName string) {&lt;br /&gt;
&amp;nbsp; if r := recover(); r != nil {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fmt.Printf(&amp;quot;%s : PANIC Defered : %v\n&amp;quot;, functionName, r)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;b&gt;// Capture the stack trace&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; buf := make([]byte, 10000)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; runtime.Stack(buf, false)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;%s : Stack Trace : %s&amp;quot;, functionName, string(buf))
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if err != nil {&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&amp;#42;err = fmt.Errorf(&amp;quot;%v&amp;quot;, r)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
As always I hope this can help you with your Go programming.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Documenting Go Code With Godoc</title><link>https://www.ardanlabs.com/blog/2013/06/documenting-go-code-with-godoc.html</link><pubDate>Wed, 05 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/documenting-go-code-with-godoc.html</guid><description>&lt;p&gt;As you know if you read my blog, I have been building a set of new utility packages so I can start developing an application server I need for a new project. I am brand new to Go and the Mac OS. Needless to say it has been one hell of an education over the past month. But I don&amp;rsquo;t miss Windows or C# at all.&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
I made some progress in my coding and wanted to build documentation for the code. I have been using the documentation viewer in LiteIDE and I was hoping to integrate my documentation in there was well. &amp;nbsp;I was really surprised to see see that LiteIDE already had my packages listed inside of their integrated Godoc viewer. So it then begged the question. How is that working?&lt;br /&gt;
&lt;br /&gt;
After some digging around I found this local HTML file. If you have LiteIDE installed you can copy the following url into your browser.&lt;br /&gt;
&lt;br /&gt;
file:///Applications/LiteIDE.app/Contents/Resources/golangdoc/about.html&lt;br /&gt;
&lt;br /&gt;
This is what it shows&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; padding: 1px 10px 10px 10px;"&gt;
&lt;h2&gt;
Overview&lt;/h2&gt;
The integrated Godoc viewer in LiteIDE provides an easy way to browse documentation generated by the godoc tool without leaving the editor. Documentation can be viewed for both the official Go language as well as custom packages. The remainder of this page describes ways to invoke the Godoc viewer.&lt;br /&gt;
&lt;h2&gt;
Supported URL Schemes&lt;/h2&gt;
It is possible to view documentation by directly entering a URL into the Godoc viewer's address bar. When doing this, you can specify what type of documentation you are looking for by prefixing the address with one of the following URL schemes:&lt;br /&gt;
&lt;h3&gt;
find&lt;/h3&gt;
Searches for packages with a specified string in their name. For example:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="find:zip"&gt;find:zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="find:godoc"&gt;find:godoc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
list&lt;/h3&gt;
Lists all packages in a given directory. The main choices are &amp;quot;pkg&amp;quot; and &amp;quot;cmd&amp;quot;, which can be found as links in the header of the page. For example:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="list:pkg"&gt;list:pkg&lt;/a&gt; - displays the Golang packages&lt;/li&gt;
&lt;li&gt;&lt;a href="list:cmd"&gt;list:cmd&lt;/a&gt; - displays the Golang commands&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
pdoc&lt;/h3&gt;
Views documentation for a specified package or command. For example:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="pdoc:fmt"&gt;pdoc:fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="pdoc:archive/zip"&gt;pdoc:archive/zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="pdoc:gofmt"&gt;pdoc:gofmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="pdoc:f:/hg/zmq/gozmq"&gt;pdoc:f:/hg/zmq/gozmq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
file&lt;/h3&gt;
Views a specified HTML, Markdown, or plain-text file. For example:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="file:///c:/go/doc/docs.html"&gt;file:c:/go/doc/docs.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Automatic Schemes&lt;/h2&gt;
For the &amp;quot;file&amp;quot; and &amp;quot;pdoc&amp;quot; schemes, you do not need to type the scheme as part of the URL. For example:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;[/doc/code.html](/broken-link)&lt;/li&gt;
&lt;li&gt;[/src/pkg](/broken-link)&lt;/li&gt;
&lt;li&gt;[/src/cmd](/broken-link)&lt;/li&gt;
&lt;li&gt;[/pkg/fmt](/broken-link)&lt;/li&gt;
&lt;li&gt;[/cmd/cgo](/broken-link) &lt;/li&gt;
&lt;li&gt;[archive/zip](/broken-link)&lt;/li&gt;
&lt;li&gt;[Go](/broken-link)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
File Browser&lt;/h2&gt;
You can open the Godoc viewer directly from the file browser by right clicking on a file or directory and selecting &amp;quot;View Godoc Here&amp;quot;. The Godoc viewer will automatically open the package documentation for the chosen item.
&lt;/div&gt;
&lt;br /&gt;
When I clicked on my package &lt;b&gt;&lt;i&gt;ArdanStudios/threadpool&amp;nbsp;&lt;/i&gt;&lt;/b&gt;from within the LiteIDE Godoc search tool it used the pdoc URL scheme,&amp;nbsp;&lt;b&gt;&lt;i&gt;pdoc:ArdanStudios/threadpool.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I quickly reasoned that LiteIDE was using the GOROOT and GOPATH variables to find the documentation. There is only one problem, I haven't created any documentation yet.&lt;br /&gt;
&lt;br /&gt;
So I looked around in both &lt;b&gt;/usr/local/go&lt;/b&gt; and my own space to find the documentation files and there was nothing. So how the heck was this documentation being generated and published on the screen?&lt;br /&gt;
&lt;br /&gt;
Then I found this document from the Go team:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/cmd/godoc/"&gt;http://golang.org/cmd/godoc/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The very first line states, &amp;quot;&lt;b&gt;&lt;i&gt;Godoc extracts and generates documentation for Go programs.&amp;quot;&lt;/i&gt;&lt;/b&gt; &amp;nbsp;Ok, so this program is being used by LiteIDE but how? &amp;nbsp;Where are the files that Godoc is generating for all this documentation?&lt;br /&gt;
&lt;br /&gt;
LOL, boy it is difficult coming from a Windows environment for the past 20 years.&lt;br /&gt;
&lt;br /&gt;
After reading the documentation a bunch of times I opened up a Terminal session and ran the following command.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;godoc /Users/bill/Spaces/GoPackages/src/ArdanStudios/threadpool&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Suddenly the documentation appeared on my screen in text format. But I am seeing HTML inside of LiteIDE? I found the&amp;nbsp;&lt;b&gt;&lt;i&gt;-html&amp;nbsp;&lt;/i&gt;&lt;/b&gt;option.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;godoc -html /Users/bill/Spaces/GoPackages/src/ArdanStudios/threadpool&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
Now I produced the same documentation I am seeing inside of LiteIDE. There are no extra files on my machine, LiteIDE is streaming the output of Godoc directly into the screen. Very smart way of doing things!!&lt;br /&gt;
&lt;br /&gt;
So if I can see documentation for the standard Go packages, then the source code for those packages must be on my machine. After a bit of looking I found them in:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;/usr/local/go/src/pkg&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
It seems they are located inside a folder called &lt;i style="font-weight: bold;"&gt;pkg&lt;/i&gt;&amp;nbsp;under &lt;i style="font-weight: bold;"&gt;src&lt;/i&gt;. This is because the Go team likes to put source code for reusable libraries within a project under &lt;b&gt;&lt;i&gt;pkg&lt;/i&gt;&lt;/b&gt;. Not all developers follow that same convention and you have the freedom to choose. I personally don't follow that convention.&amp;nbsp;Apparently the Godoc tool has no problems finding the source code files.&lt;br /&gt;
&lt;br /&gt;
Godoc tool is always reading the source code files to produce the latest version of the documentation. So in LiteIDE when you update your documentation and save the code file, the Godoc tool will show the changes immediately.&lt;br /&gt;
&lt;br /&gt;
Now the next problem I have, my documentation looks really bad. The documentation that I see from the standard library files looks much better. So how do I format my documentation properly inside the Go code files?&lt;br /&gt;
&lt;br /&gt;
I found this document from the Go team:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/doc/articles/godoc_documenting_go_code.html"&gt;http://golang.org/doc/articles/godoc_documenting_go_code.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The introduction reads:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; padding: 1px 10px 10px 10px;"&gt;
&lt;h2&gt;
Godoc: documenting Go code&lt;/h2&gt;
&lt;b&gt;The Go project takes documentation seriously&lt;/b&gt;. Documentation is a huge part of making software accessible and maintainable. Of course it must be well-written and accurate, but it also must be easy to write and to maintain. Ideally, it should be coupled to the code itself so the documentation evolves along with the code. The easier it is for programmers to produce good documentation, the better for everyone.&lt;br /&gt;
&lt;br /&gt;
To that end, we have developed the godoc documentation tool. This article describes godoc's approach to documentation, and explains how you can use our conventions and tools to write good documentation for your own projects.&lt;br /&gt;
&lt;br /&gt;
Godoc parses Go source code - including comments - and produces documentation as HTML or plain text. The end result is documentation tightly coupled with the code it documents. For example, through godoc's web interface you can navigate from a function's documentation to its implementation with one click.&lt;/div&gt;
&lt;br /&gt;
Coming from the C# world and using XML tags like &amp;lt;summary&amp;gt; for that past 10 years and having to remember to check the &amp;quot;produce XML documentation file&amp;quot; option, this was a dream. Oh yea, no extra documentation file.&lt;br /&gt;
&lt;br /&gt;
However the rest of the page was lacking. I liked the way the documentation for fmt.Printf looked so I quickly found the go source files and studied what the programmer did. After a bit of playing I finally figured out the 3 basic rules you need to help the Godoc tool format the documentation cleanly.&lt;br /&gt;
&lt;br /&gt;
Here is a sample of the documentation I have for my tracelog package:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen-Shot-2013-07-28-at-9.57.53-AM.png)
&lt;/div&gt;
&lt;br /&gt;
There are 3 elements in play when writing your documentation. You have header sections, standard text and highlighted text.&lt;br /&gt;
&lt;br /&gt;
At the very top of your code file add the following using the // comment operation or something similar. Obviously you want to give yourself the credit for your work, LOL.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #38761d; font-family: Courier New, Courier, monospace;"&gt;// Copyright 2022 Ardan Studios. All rights reserved.&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #38761d; font-family: Courier New, Courier, monospace;"&gt;// Use of this source code is governed by a BSD-style&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #38761d; font-family: Courier New, Courier, monospace;"&gt;// license that can be found in the LICENSE file.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Then add a block comment operator and we can start. Make sure the &lt;i style="font-weight: bold;"&gt;package&lt;/i&gt;&amp;nbsp;code statement is exactly after the closing comment operator. There can not be no blank lines between the two.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Tabbing is very important. We are using two layers of tabbing. Keep these two layers of tabbing consistent.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #38761d; font-family: Courier New, Courier, monospace;"&gt;/&amp;#42;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; Package TraceLog implements a file based logging.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; The programmer should feel free to tace log as much of the code.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fce5cd; font-family: Courier New, Courier, monospace;"&gt;-&amp;gt;CRLF&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; New Parameters&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fce5cd; font-family: Courier New, Courier, monospace;"&gt;-&amp;gt;CRLF&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; The following is a list of parameters for creating a TraceLog:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; baseFilePath: The base location to store all log directories.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; machineName: The name of the machine or system. Information is used.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; writeToStdout: Set to True if you want the system to also write.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fce5cd; font-family: Courier New, Courier, monospace;"&gt;-&amp;gt;CRLF&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; TraceLog File Management&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fce5cd; font-family: Courier New, Courier, monospace;"&gt;-&amp;gt;CRLF&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; Every 2 minutes TraceLog will check each open file for two conditions:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fce5cd; font-family: Courier New, Courier, monospace;"&gt;-&amp;gt;CRLF&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; 1. Has a message been written to the file within the last 2 minutes.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background-color: #fce5cd;"&gt;-&amp;gt;TAB&lt;/span&gt;&lt;span style="color: #38761d;"&gt; 2. Is the size of the file greater than 10 Meg.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&amp;#42;/&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&lt;span style="color: #0b5394;"&gt;package&lt;/span&gt;&lt;/b&gt; tracelog&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The first section of comments will show at the top of our documentation just below the Overview Section. Also the first sentence will appear in Godoc's package list.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Then we have a blank line and a string that will become a header as long as the next line is double spaced and has the same indentation.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The final component is the second tabbing indentation. This will cause that text to be highlighted with a grey background.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You may need to remove all of your existing documentation from your Go code file and throw it into a text editor. Then put it back in to make sure all the tabs and carriage returns are clean.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Using GoDoc.org&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you are building a public package you can use the GoDoc website to publish your documentation. Check out the GoDoc website:&lt;br /&gt;
&lt;br /&gt;
[http://godoc.org/] (http://godoc.org/)
&lt;br /&gt;
&lt;br /&gt;
This website has been setup to read your code files and display all of your great documentation. Enter this url (github.com/goinggo/utilities/v1/workpool) into the search box and see the documentation that GoDoc produces for my workpool package:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen-Shot-2013-09-02-at-12.33.05-PM.png)
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen-Shot-2013-09-02-at-12.33.23-PM.png)
&lt;/div&gt;
&lt;br /&gt;
You can see the same documentation that is being given to you locally is now published on the GoDoc website with your own reuseable url:&lt;br /&gt;
&lt;br
[http://godoc.org/github.com/goinggo/utilities/v1/workpool](/broken-link)&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So how can you best use this url to provide people your documentation? When you create a repository for your package add a README.md file. This is a special "Markdown" file that supports standard text, html and a few special operators of its own. Github has its own extensions and you can find documentation about Markdown here:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://help.github.com/articles/github-flavored-markdown" target="_blank"&gt;https://help.github.com/articles/github-flavored-markdown&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If you happened to come across my public workpool package in Github, you would see the following:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen-Shot-2013-09-02-at-12.45.10-PM.png)
&lt;/div&gt;
&lt;br /&gt;
There is my code file, license file and my readme Markdown file.&lt;br /&gt;
&lt;br /&gt;
Here is a typical README Markdown file that I use:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #efefef; font-family: Courier New, Courier, monospace; font-size: small; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;
# Workpool - Version 1.0.0&lt;br /&gt;
&lt;br /&gt;
Copyright 2022 Ardan Studios. All rights reserved.&amp;lt;br /&amp;gt;&lt;br /&gt;
Use of this source code is governed by a BSD-style license that can be found in the LICENSE handle.&lt;br /&gt;
&lt;br /&gt;
Ardan Studios&amp;lt;br /&amp;gt;&lt;br /&gt;
12973 SW 112 ST, Suite 153&amp;lt;br /&amp;gt;&lt;br /&gt;
Miami, FL 33186&amp;lt;br /&amp;gt;&lt;br /&gt;
bill@ardanstudios.com&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[Click To View Documentation](/broken-link)
&lt;/div&gt;
&lt;br /&gt;
View The Raw Version Here:&lt;br /&gt;
[https://raw.github.com/goinggo/utilities/master/v1/workpool/README.md](/broken-link)
&lt;br /&gt;
&lt;br /&gt;
Look at the Markdown link at the bottom of the file. This syntax creates a link to the documentation. The text in the hard brackets [], provides the anchor text for the link.&lt;br /&gt;
&lt;br /&gt;
Since Github always display the Readme Markdown file to the user if one exists, this is what people see when they come to that Github page:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen-Shot-2013-09-02-at-12.50.23-PM.png)
&lt;/div&gt;
&lt;br /&gt;
Now people have access to the documentation I write on the web as well. I don't need to copy and paste the documentation into the Readme Markdown file, just provide a link. All the documentation is in one place and formatted cleanly and consistently.&lt;br /&gt;
&lt;br /&gt;
As always, I hope this helps you in some small way and your documentation draws people to your work.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</description></item><item><title>Installing Go, Gocode, GDB and LiteIDE</title><link>https://www.ardanlabs.com/blog/2013/06/installing-go-gocode-gdb-and-liteide.html</link><pubDate>Sun, 02 Jun 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/06/installing-go-gocode-gdb-and-liteide.html</guid><description>&lt;p&gt;Check out my new installtion document:&lt;br /&gt;
&lt;a href="https://www.ardanlabs.com/blog/2016/05/installing-go-and-your-workspace.html" target="_blank"&gt;&lt;a href="https://www.ardanlabs.com/blog/2016/05/installing-go-and-your-workspace.html"&gt;https://www.ardanlabs.com/blog/2016/05/installing-go-and-your-workspace.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;I removed the sections about gocode and GDB. These are not necessary any longer. I also added links for more editors.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;Windows&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
This is a great post by &lt;a href="https://twitter.com/WadeWegner" target="_blank"&gt;Wade Wegner&lt;/a&gt; for installing Go on your Windows Machine:&lt;br /&gt;
&lt;a href="http://www.wadewegner.com/2014/12/easy-go-programming-setup-for-windows/" target="_blank"&gt;&lt;a href="http://www.wadewegner.com/2014/12/easy-go-programming-setup-for-windows/"&gt;http://www.wadewegner.com/2014/12/easy-go-programming-setup-for-windows/&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;
&lt;span style="font-size: x-large;"&gt;Mac OS X&lt;/span&gt;&lt;span style="font-size: small; font-weight: normal;"&gt;&lt;br /&gt;The following instructions will guide you through installing Go on your Mac.&lt;/span&gt;&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 1: Download Go&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;
Open your favorite browser and go to the following website:&lt;br /&gt;
&lt;a href="http://golang.org/dl/" target="_blank"&gt;http://golang.org/dl/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="margin:0 auto; display:block; width:640px;"&gt;
![Screen Shot](../../../images/goinggo/Screen+Shot+2015-08-29+at+8.57.08+PM.png)
&lt;/div&gt;
&lt;br /&gt;
This will show you all the latest builds for the different operating systems. Darwin is the name for the Mac OS. Download the installer package for your OS version and architecture.&lt;br /&gt;
&lt;br /&gt;
Once downloaded go to your Downloads folder in Finder and double click on the pkg file to start the installation. The installation will put Go in &lt;b&gt;&lt;i&gt;/usr/local/go&lt;/i&gt;&lt;/b&gt;. Once the installation is complete you will want to check the installation.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Note: Moving forward we will be using both Terminal and Finder. It helps to be able to see all the files in Finder. &amp;nbsp;Finder by default will not show you everything that is on your hard drive.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;b&gt;&lt;i&gt;To show all files in Finder:&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Open a Terminal session.&amp;nbsp;If you don't know where the Terminal program is go to your Applications folder in Finder and then Utilities. Click on Terminal and a bash shell command window will open.&lt;br /&gt;
&lt;br /&gt;
Execute the following commands in Terminal.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
defaults write com.apple.finder AppleShowAllFiles TRUE&lt;br /&gt;
killall Finder&lt;/div&gt;
&lt;br /&gt;
The &lt;b&gt;&lt;i&gt;killall Finder&lt;/i&gt;&lt;/b&gt; will reload the Finder program and now you can see all the files.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 2: &amp;nbsp;Check Installation&lt;/b&gt;&lt;/h3&gt;
Open a Terminal session and type the following command&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
go version&lt;/div&gt;
&lt;br /&gt;
You should see the following if everything installed correctly&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
go version go1.5 darwin/amd64&lt;/div&gt;
&lt;br /&gt;
Now type the &lt;b&gt;&lt;i&gt;which&lt;/i&gt;&lt;/b&gt; command to verify the installation is in &lt;b&gt;&lt;i&gt;/usr/local/go&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
which go&lt;/div&gt;
&lt;br /&gt;
You should see that Go can be found in &lt;b&gt;&lt;i&gt;/usr/local/go/bin&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
/usr/local/go/bin/go&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 3: &amp;nbsp;Set Your GOPATH&lt;/b&gt;&lt;/h3&gt;
You need a single place to store and work on your Go projects. Create a folder called projects from inside your home folder:
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
cd $HOME&lt;/div&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
mkdir projects&lt;br /&gt;
cd projects&lt;br /&gt;
mkdir src&lt;br /&gt;
mkdir bin&lt;/div&gt;
&lt;br /&gt;
Now set projects as your GOPATH. Open the .bash_profile file from the $HOME folder and add the following items to the end.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
nano .bash_profile&lt;/div&gt;
&lt;br /&gt;
export GOPATH="$HOME/projects"&lt;br /&gt;
export PATH=$PATH:$GOPATH/bin
&lt;br /&gt;
&lt;br /&gt;
Then exit the Terminal App and open a new Terminal App. Check that the Go environment now has your new GOPATH.
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
go env&lt;/div&gt;
&lt;br /&gt;
You should see all the Go related environment variables including GOPATH. Here are some of them:&lt;br /&gt;
&lt;br /&gt;
GOARCH="amd64"&lt;br /&gt;
GOHOSTARCH="amd64"&lt;br /&gt;
GOHOSTOS="darwin"&lt;br /&gt;
GOOS="darwin"&lt;br /&gt;
&lt;b&gt;GOPATH="/Users/you/projects"&lt;/b&gt;&lt;br /&gt;
GOROOT="/usr/local/go"&lt;br /&gt;
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 4: &amp;nbsp;Get, Build and Install Basic Packages&lt;/b&gt;&lt;/h3&gt;
These are Go packages you may want:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #666666; color: #cccccc; padding: 5px;"&gt;
// gocode is used by many editors to provide intellisense&lt;br /&gt;
go get github.com/nsf/gocode&lt;br /&gt;
&lt;br /&gt;
// goimports is something you should run when saving code to fill in import paths&lt;br /&gt;
go get golang.org/x/tools/cmd/goimports&lt;br /&gt;
&lt;br /&gt;
// gorename is used by many editors to provide identifier rename support&lt;br /&gt;
go get golang.org/x/tools/cmd/gorename&lt;br /&gt;
&lt;br /&gt;
// oracle is a tool that help with code navigation and search&lt;br /&gt;
go get golang.org/x/tools/cmd/oracle&lt;br /&gt;
&lt;br /&gt;
// golint should be run after every build to check your code&lt;br /&gt;
go get github.com/golang/lint/golint&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 5: &amp;nbsp;Debugger&lt;/b&gt;&lt;/h3&gt;
Using GDB is really not an option. If you would like to experiment with Delve, here is a link:&lt;br /&gt;
&lt;a href="https://github.com/derekparker/delve"&gt;https://github.com/derekparker/delve&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Step 6: Install Editor&lt;/b&gt;&lt;/h3&gt;
&lt;b&gt;&lt;br /&gt;Sublime&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.sublimetext.com/" target="_blank"&gt;http://www.sublimetext.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
DisposaBoy wrote this plugin for Sublime&lt;br /&gt;
&lt;a href="https://github.com/DisposaBoy/GoSublime" target="_blank"&gt;https://github.com/DisposaBoy/GoSublime&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Mark Wolfe wrote this post:&lt;br /&gt;
&lt;a href="http://www.wolfe.id.au/2015/03/05/using-sublime-text-for-go-development/" target="_blank"&gt;http://www.wolfe.id.au/2015/03/05/using-sublime-text-for-go-development/&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;VIM&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.vim.org/download.php" target="_blank"&gt;http://www.vim.org/download.php&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Victor Farazdagi wrote this post on installing Vim for Go:&lt;br /&gt;
&lt;a href="http://farazdagi.com/blog/2015/vim-as-golang-ide/" target="_blank"&gt;http://farazdagi.com/blog/2015/vim-as-golang-ide/&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Atom&lt;/b&gt;&lt;br /&gt;
&lt;a href="https://atom.io/" target="_blank"&gt;https://atom.io/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Joe Fitzgerald wrote this plugin for Atom&lt;br /&gt;
&lt;a href="https://github.com/joefitzgerald/go-plus" target="_blank"&gt;https://github.com/joefitzgerald/go-plus&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;LiteIDE&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://sourceforge.net/projects/liteide/files/" target="_blank"&gt;http://sourceforge.net/projects/liteide/files/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Emacs&lt;/b&gt;&lt;br /&gt;
This is the configuration Guillaume Charmes uses:&lt;br /&gt;
&lt;a href="https://github.com/creack/dotfiles"&gt;https://github.com/creack/dotfiles&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;Helpful Links&lt;/b&gt;&lt;/h3&gt;
Here are other links to web pages that will be very helpful:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://golang.org/" target="_blank"&gt;http://golang.org/&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://github.com/golang/go/wiki"&gt;https://github.com/golang/go/wiki&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.golang.org/" target="_blank"&gt;http://blog.golang.org/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.youtube.com/user/gocoding" target="_blank"&gt;http://www.youtube.com/user/gocoding&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://dave.cheney.net/" target="_blank"&gt;http://dave.cheney.net/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gophervids.appspot.com/" target="_blank"&gt;http://gophervids.appspot.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You must watch these videos on Go Concurrency Patterns&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.youtube.com/watch?v=QDDwwePbDtw" target="_blank"&gt;http://www.youtube.com/watch?v=QDDwwePbDtw&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.youtube.com/watch?v=f6kdp27TYZs" target="_blank"&gt;http://www.youtube.com/watch?v=f6kdp27TYZs&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Thread Pooling in Go Programming</title><link>https://www.ardanlabs.com/blog/2013/05/thread-pooling-in-go-programming.html</link><pubDate>Fri, 31 May 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/05/thread-pooling-in-go-programming.html</guid><description>&lt;p&gt;&lt;i&gt;After working in Go for some time now, I learned how to use an unbuffered channel to build a pool of goroutines. I like this implementation better than what is implemented in this post.  That being said, this post still has value in what it describes.&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;a href="https://github.com/goinggo/work" target="_blank"&gt;&lt;a href="https://github.com/goinggo/work"&gt;https://github.com/goinggo/work&lt;/a&gt;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
In my world of server development thread pooling has been the key to building robust code on the Microsoft stack. Microsoft has failed in .Net by giving each Process a single thread pool with thousands of threads and thinking they could manage the concurrency at runtime. Early on I realized this was never going to work. At least not for the servers I was developing.&lt;br /&gt;
&lt;br /&gt;
When I was building servers in C/C++ using the Win32 API, I created a class that abstracted IOCP to give me thread pools I could post work into. This has always worked very well because I could define the number of threads in the pool and the concurrency level (the number of threads allowed to be active at any given time).  I ported this code for all of my C# development. If you want to learn more about this, I wrote an article years ago (&lt;a href="http://www.theukwebdesigncompany.com/articles/iocp-thread-pooling.php" target="_blank"&gt;&lt;a href="http://www.theukwebdesigncompany.com/articles/iocp-thread-pooling.php"&gt;http://www.theukwebdesigncompany.com/articles/iocp-thread-pooling.php&lt;/a&gt;&lt;/a&gt;). Using IOCP gave me the performance and flexibility I needed. BTW, the .NET thread pool uses IOCP underneath.&lt;br /&gt;
&lt;br /&gt;
The idea of the thread pool is fairly simple. Work comes into the server and needs to get processed. Most of this work is asynchronous in nature but it doesn&amp;rsquo;t have to be. Many times the work is coming off a socket or from an internal routine. The thread pool queues up the work and then a thread from the pool is assigned to perform the work. The work is processed in the order it was received. The pool provides a great pattern for performing work efficiently. Spawning a new thread everytime work needs to be processed can put heavy loads on the operating system and cause major performance problems.&lt;br /&gt;
&lt;br /&gt;
So how is the thread pool performance tuned? You need to identify the number of threads each pool should contain to get the work done the quickest. When all the routines are busy processing work, new work stays queued. You want this because at some point having more routines processing work slow things down. This can be for a myriad of reasons such as, the number of cores you have in your machine to the ability of your database to handle requests. During testing you can find that happy number.&lt;br /&gt;
&lt;br /&gt;
I always start with looking at how many cores I have and the type of work being processed. Does this work get blocked and for how long on average. On the Microsoft stack I found that three active threads per core seemed to yield the best performance for most tasks. I have no idea yet what the numbers will be in Go.&lt;br /&gt;
&lt;br /&gt;
You can also create different thread pools for the different types of work the server will need to process. Because each thread pool can be configured, you can spend time performance tuning the server for maximum throughput. Having this type of command and control to maximize performance is crucial.&lt;br /&gt;
&lt;br /&gt;
In Go we don&amp;rsquo;t create threads but routines. The routines function like multi-threaded functions but Go manages the actual use of OS level threading. To learn more about concurrency in Go check out this document: &lt;a href="http://golang.org/doc/effective_go.html#concurrency"&gt;&lt;a href="http://golang.org/doc/effective_go.html#concurrency"&gt;http://golang.org/doc/effective_go.html#concurrency&lt;/a&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The packages I have created are called workpool and jobpool. These use the channel and go routine constructs to implement pooling.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Workpool&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This package creates a pool of go routines that are dedicated to processing work posted into the pool. A single Go routine is used to queue the work. The queue routine provides the safe queuing of work, keeps track of the amount of work in the queue and reports an error if the queue is full.&lt;br /&gt;
&lt;br /&gt;
Posting work into the queue is a blocking call. This is so the caller can verify that the work is queued. Counts for the number of active worker routines are maintained.&lt;br /&gt;
&lt;br /&gt;
Here is some sample code on how to use the workpool:&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description></item><item><title>Why Go Programming</title><link>https://www.ardanlabs.com/blog/2013/05/why-go-programming.html</link><pubDate>Fri, 31 May 2013 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/blog/2013/05/why-go-programming.html</guid><description>&lt;p&gt;For the past 20 years I have been writing server based and application software on the Microsoft stack. First in C/C++ leveraging the Win32 API and then in C# when .Net first was released. Over the past few months I have realized that trying to build scalable code on the Microsoft stack is becoming impossible. Why, Technology and Cost!!&lt;br /&gt;&lt;/p&gt;
&lt;br /&gt;
Let's start with the licensing. Luckily I was accepted into the Bizspark program. If I didn't have that I would be looking at thousands of dollars to just get access to the tooling I need. Real world applications require a database. If you want to use SQL Server Standard the licensing model is not only convoluted but outrageously expensive once you figure all that out. If I am building something for a client and they need something more than SQL Express I am doing them an injustice. Even using SQL Server in the cloud is no picnic on pricing. Then you have CPU and Memory requirements. I am sorry but trying to run a SQL Server and IIS on anything less than 4 Gig is impossible. &amp;nbsp;Lastly, take this cost for one machine and try to build a scalable architecture around it and your costs are through the roof.&lt;br /&gt;
&lt;br /&gt;
I don't think it is an accident that Facebook, Twitter and the like are running on linux based technologies. The linux based technologies are cheaper, faster and require much less metal. You can build larger systems and architectures for fractions of the cost. These are proven technologies that are driving the biggest websites today.&lt;br /&gt;
&lt;br /&gt;
I have already moved away from SQL Server to MongoDB. MongoDB has been a real win in terms of development, devops and cost. It has been around since 2009, has a huge community of people supporting it and there are drivers for just about every programming language. In fact, I have been able to do more with MongoDB than I could with SQL Server. &amp;nbsp;Oh yea, no cost !!&lt;br /&gt;
&lt;br /&gt;
For web development I am now using Ruby on Rails. This was an easy transition from .Net MVC and I use RubyMine as my IDE. RubyMine is a great tool and it only costs $100. If you are building just web services then using Padrino is a great way to go.&lt;br /&gt;
&lt;br /&gt;
Now the rub, building application servers on the linux stack. I didn't want to use C/C++, I was done with that. Someone suggested Ruby but I have never felt it was a great language for server development. I looked at Erlang but that wasn't right. So I continued to use my C# based Windows service I called the TaskServer.&lt;br /&gt;
&lt;br /&gt;
My TaskServer is really cool. It is a Windows service framework that can load and unload DLL based packages at runtime. Each Plugin is loaded into its own application domain. I added facilities to abstract threading, internal and external plugin communication, trace logging and anything I could do to make Plugin development fast and easy. &amp;nbsp;The TaskServer has served me well but it runs on the Microsoft stack. For my Ruby web apps to talk with it I use RabbitMQ. Eventually I was going to build a Gem that implemented the Socket protocol so I could talk to the server directly.&lt;br /&gt;
&lt;br /&gt;
Then someone told me to look at Go Programming. After reading and watching a few videos I was blown away. This is what I have been searching for. A programming language tailored to server development that would run on the linux stack. I have been able to take all of my C/C++/C# experience and quickly learn the language. Obviously the&amp;nbsp;goroutine/channel&amp;nbsp;construct is quite different but once you get your head wrapped around it you realize how much easier it makes concurrent programming.&lt;br /&gt;
&lt;br /&gt;
As with any new language my first step is to port my utility classes and I have already begun that work. I have finished my ThreadPool package and now I am working on my TraceLog package. Once that is done I am moving to MongoDB and then will begin to build a server that will manage large amounts of data imports for a project I am working on, Details soon to come.&lt;br /&gt;
&lt;br /&gt;
This is the beginning of my journey in Go Programming and never looking back at the Microsoft stack again. Sorry VMWare but I hope I never need to upgrade you again.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Advanced Kubernetes and Docker Training for Teams &amp; Individuals - Ardan Labs</title><link>https://www.ardanlabs.com/training/live/teams/intensive-docker-kubernetes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/live/teams/intensive-docker-kubernetes/</guid><description>&lt;ul class="flex flex-row flex-wrap gap-3"&gt;
 &lt;li class="badge shadow"&gt;Control Plane&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Kubectl&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Service Discovery&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Kustomize&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Capacity Management&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Pod Security&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Helm&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Stateful Applications&lt;/li&gt;
 &lt;li class="badge shadow"&gt;&amp; more&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Advanced Kubernetes Training</title><link>https://www.ardanlabs.com/team-live-training-courses/kubernetes_administrator_training/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/kubernetes_administrator_training/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;This course covers advanced topics like security, capacity planning (including autoscaling), Kubernetes API extensions points (including operators and CRDs), and presents a number of popular operators. It is a great addition to the &amp;ldquo;Kubernetes Bootstrap&amp;rdquo;, but can also be taken independently by folks who have a bit of Kubernetes experience and are familiar with key concepts like Pods, Deployments, Services, working with YAML, and want to take their Kubernetes mastery to the next level.&lt;/p&gt;</description></item><item><title>Advanced Rust Training for Teams &amp; Individuals - Ardan Labs</title><link>https://www.ardanlabs.com/training/live/teams/rust/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/live/teams/rust/</guid><description>&lt;ul class="flex flex-row flex-wrap gap-4"&gt;
 &lt;li class="badge shadow"&gt;The Rust Ecosystem&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Data Management&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Fearless Concurrency&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Traits, and Generics&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Rust as a Service&lt;/li&gt;
 &lt;li class="badge shadow"&gt;More Integrations&lt;/li&gt;
 &lt;li class="badge shadow"&gt;&amp; more&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Custom Practical Go Training and Boot Camps</title><link>https://www.ardanlabs.com/team-live-training-courses/custom_practical_go_training/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/custom_practical_go_training/</guid><description>&lt;h3 id="course-description"&gt;Course Description:&lt;/h3&gt;
&lt;p&gt;Our custom hands-on Go training contains several modules that you can choose from to create a syllabus tailored to your needs. Feel free to reach out if you have a need that is not converted by the following topics - we have a lot of experience with Go and development at large.&lt;/p&gt;
&lt;p&gt;These classes are led by Miki Tebeka. Miki has more than 25 years of experience developing software for clients, with 11 of those years writing code in Go. Miki is the author of several books, a LinkedIn Learning author and a very busy teacher. Miki teaching style is “hands on” - you’re going to write a lot of coding during these sessions.&lt;/p&gt;</description></item><item><title>Deep Dive Into Kubernetes Networking with CNI</title><link>https://www.ardanlabs.com/self-paced-courses/deep-div-into-kubertnetes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/deep-div-into-kubertnetes/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course is for devs, ops, or even architects, who want to dive deeper into Kubernetes and learn concepts around the Container Network Interface (CNI). We&amp;rsquo;ll discuss CNI plugins and how pods communicate together on Kubernetes. As an example, we will change the CNI plugin on a live Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;This course is part of the Intensive Docker &amp;amp; Kubernetes track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;</description></item><item><title>Go, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/go-k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/go-k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Go, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 100 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/go-k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/go-k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Go, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 100 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Docker &amp; K8s Performance Bundle</title><link>https://www.ardanlabs.com/self-paced-individuals/performance-bundles/go_k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-individuals/performance-bundles/go_k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Go, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 100 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Docker &amp; K8s Performance Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/performance-bundles/go_k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/performance-bundles/go_k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Go, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 100 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Rust, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/mastery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/mastery/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Go, Rust, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 214 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Rust, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/mastery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/mastery/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Go, Rust, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 214 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Rust, Docker &amp; K8s Mastery Bundle</title><link>https://www.ardanlabs.com/self-paced-individuals/mastery-bundle/master-bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-individuals/mastery-bundle/master-bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Go, Rust, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 214 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go, Rust, Docker &amp; K8s Mastery Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/mastery-bundle/master-bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/mastery-bundle/master-bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Go, Rust, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 214 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Intensive Docker</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate-docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate-docker/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course will help you establish foundational concepts of Docker &amp;amp; containers. You’ll complete labs and assignments that will help you become productive at designing, packaging, deploying and operating modern applications.&lt;/p&gt;
&lt;p&gt;This course is part of the Intensive Docker &amp;amp; Kubernetes track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item><item><title>Intensive Docker &amp; K8s Bundle</title><link>https://www.ardanlabs.com/self-paced-individuals/core-bundles/k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-individuals/core-bundles/k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Fundamentals&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Advanced Engineering&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Cloud Native Environments&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; High Performance Concepts&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Intensive Docker &amp; K8s Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/core-bundles/k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/core-bundles/k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Fundamentals&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Advanced Engineering&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Cloud Native Environments&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; High Performance Concepts&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Intensive Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Fundamentals&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Advanced Engineering&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Cloud Native Environments&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;High Performance Concepts&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Networking with CNI&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Intensive Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Fundamentals&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Advanced Engineering&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Cloud Native Environments&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;High Performance Concepts&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-5 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Networking with CNI&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Intensive Docker Training</title><link>https://www.ardanlabs.com/team-live-training-courses/intensive_docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/intensive_docker/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;This course will enable you to leverage Docker to build, ship, and run traditional and microservices applications in containers, both in local development and production environments. You will learn how to start/stop/manage containers with the Docker CLI, build optimized container images with Dockerfiles, multi-stage builds, advanced BuildKit features, and more. You will also see how to set up repeatable development stacks of containers with Compose, and how to take them to production.&lt;/p&gt;</description></item><item><title>Intensive Kubernetes</title><link>https://www.ardanlabs.com/self-paced-courses/intensive-kubernetes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/intensive-kubernetes/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This is a course for any engineer who needs to deploy, scale, and operate applications in &amp;ldquo;Cloud Native&amp;rdquo; environments. You’ll complete labs and assignments that will help you become productive with Kubernetes.&lt;/p&gt;
&lt;p&gt;This course is part of the Intensive Docker &amp;amp; Kubernetes track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item><item><title>Intensive Kubernetes: Advanced Concepts</title><link>https://www.ardanlabs.com/self-paced-courses/intensive-kubernetes-adv-concepts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/intensive-kubernetes-adv-concepts/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course is for devs, ops, and architects, who have already started working with Kubernetes and want to learn more advanced concepts. Students will complete numerous labs and exercises.&lt;/p&gt;
&lt;p&gt;This course is part of the Intensive Docker &amp;amp; Kubernetes track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understanding of Pods, Deployments, Services.&lt;/li&gt;
&lt;li&gt;How to deploy an app and expose it on a Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Basic notions of what are labels, selectors, YAML manifests.&lt;/li&gt;
&lt;li&gt;Basic shell commands (navigate directories, set environment variables…).&lt;/li&gt;
&lt;li&gt;Using a text editor like vi, nano, or similar.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Day 1: security focus:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Securing access with network policies&lt;/li&gt;
&lt;li&gt;Managing permissions with RBAC&lt;/li&gt;
&lt;li&gt;Managing secrets with Sealed Secrets&lt;/li&gt;
&lt;li&gt;Pod Security Settings and Admission&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Day 2: resource management:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Understanding requests and limits&lt;/li&gt;
&lt;li&gt;Compressible vs incompressible resources&lt;/li&gt;
&lt;li&gt;Pod eviction and kubelet under pressure&lt;/li&gt;
&lt;li&gt;Horizontal, vertical, and cluster- autoscaling&lt;/li&gt;
&lt;li&gt;Priorities and preemption&lt;/li&gt;
&lt;li&gt;Scaling with custom metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Day 3: extending the Kubernetes API:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Overview of the different extension mechanisms&lt;/li&gt;
&lt;li&gt;Custom Resource Definitions&lt;/li&gt;
&lt;li&gt;Dynamic admission control with webhooks&lt;/li&gt;
&lt;li&gt;The aggregation layer&lt;/li&gt;
&lt;li&gt;Operator concepts&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Day 4: operator and controller implementation:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Operator design techniques&lt;/li&gt;
&lt;li&gt;Studying operators (e.g. Kyverno, cert-manager)&lt;/li&gt;
&lt;li&gt;The kubebuilder framework&lt;/li&gt;
&lt;li&gt;Writing a small operator with kubebuilder&lt;/li&gt;
&lt;li&gt;Events, finalizers, owners and dependents&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Day 5: stateful applications:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Stateful Sets, PV, PVC, Storage Classes&lt;/li&gt;
&lt;li&gt;Use-case: running a Consul cluster&lt;/li&gt;
&lt;li&gt;Dynamic storage provisioning&lt;/li&gt;
&lt;li&gt;Use-case: stateful failover of an active database&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Introduction to KinD</title><link>https://www.ardanlabs.com/self-paced-courses/intro-to-kind/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/intro-to-kind/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Learn how to use KinD (Kubernetes-in-Docker) to get a local Kubernetes cluster across Linux, Mac, and Windows environments.&lt;/p&gt;
&lt;p&gt;KinD is primarily used for testing Kubernetes but can also be utilized for local development or CI.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No experience with containers necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Introduction to KinD:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;1.0 - Using KinD for local Kubernetes development&lt;/li&gt;
&lt;li&gt;1.2 - 5 options for running Kubernetes locally&lt;/li&gt;
&lt;li&gt;1.3 - Deploying a KinD cluster with multiple nodes&lt;/li&gt;
&lt;li&gt;1.4 - Utilizing docker exec/docker stats with KinD&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Kubernetes Bootstrap Training</title><link>https://www.ardanlabs.com/team-live-training-courses/kubernetes_bootstrap/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/kubernetes_bootstrap/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;Whether you are completely new to Kubernetes or are already dabbling in it, this course will give you a solid understanding of Kubernetes concepts and architecture without skimming on the details. You&amp;rsquo;ll learn how to deploy, update, scale, and troubleshoot applications on Kubernetes clusters, both on-premises or on-cloud.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes concepts and architecture&lt;/li&gt;
&lt;li&gt;Pods and pod controllers: Replica Sets, Deployments, Jobs, Daemon Sets…&lt;/li&gt;
&lt;li&gt;Exposing pods with services and ingresses&lt;/li&gt;
&lt;li&gt;Annotations, labels, and selectors&lt;/li&gt;
&lt;li&gt;Managing logs and troubleshooting common issues&lt;/li&gt;
&lt;li&gt;Organizing resources with Namespaces&lt;/li&gt;
&lt;li&gt;Writing, generating, and deploying with YAML manifests&lt;/li&gt;
&lt;li&gt;Working with local development clusters as well as remote ones&lt;/li&gt;
&lt;li&gt;Scaling and failover&lt;/li&gt;
&lt;li&gt;Rolling updates, healthchecks&lt;/li&gt;
&lt;li&gt;Advanced patterns like blue/green deployments&lt;/li&gt;
&lt;li&gt;Understanding volumes and using them for data sharing&lt;/li&gt;
&lt;li&gt;Managing application configuration with ConfigMaps, downward API, and more&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Kubernetes Controller Training</title><link>https://www.ardanlabs.com/team-live-training-courses/kubernetes_controller_training/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/kubernetes_controller_training/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;Understanding and extending the Kubernetes control plane. The Kubernetes control plane is arguably the most successful orchestration engine ever built. This course will dive into how it works and the concepts behind why it’s so effective. We will demonstrate how anyone can extend the control plane with additional functionality by building a production-grade controller through a series of exercises. All concepts are communicated through live diagrams and reinforced through joint coding sessions. Most teams find this material useful to kickstart company-projects after the course. By the end of this course, you will have the tools necessary to detangle the set of pipelines, scripts, lambda functions, and cron jobs that orchestrate software at most companies.&lt;/p&gt;</description></item><item><title>Managing AWS Resources with Terraform</title><link>https://www.ardanlabs.com/self-paced-courses/managing-aws-resources-with-terraform/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/managing-aws-resources-with-terraform/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Get started with the basics of Infrastructure-as-code and see a live demo on how to spin up a web server with Terraform.&lt;/p&gt;
&lt;p&gt;This course is part of the Intensive Docker &amp;amp; Kubernetes track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Students should be comfortable using the command line.&lt;/li&gt;
&lt;li&gt;Some experience with Kubernetes recommended.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Managing AWS With Terraform:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;1.1.1 - What is Infrastructure as Code (IaC)&lt;/li&gt;
&lt;li&gt;1.1.2 - Benefits of Terraform&lt;/li&gt;
&lt;li&gt;1.1.3 - Getting Started: Basic Terraform Commands&lt;/li&gt;
&lt;li&gt;1.1.4 - Example Terraform Configuration File&lt;/li&gt;
&lt;li&gt;1.1.5 - Intro to Terraform .tf Files&lt;/li&gt;
&lt;li&gt;1.1.6 - Creating AWS resources with Terraform&lt;/li&gt;
&lt;li&gt;1.1.7 - Enabling SSH connectivity with Terraform&lt;/li&gt;
&lt;li&gt;1.1.8 - Turning our server into a web server&lt;/li&gt;
&lt;li&gt;1.1.9 - Making the server production ready&lt;/li&gt;
&lt;li&gt;1.2.0 - Creating an S3 bucket with Terraform&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Performance Go for Developers</title><link>https://www.ardanlabs.com/team-live-training-courses/performance_go_for_developers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/performance_go_for_developers/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Performance Go for Developers training class is aimed for experienced Go developers who’d like to extend their knowledge.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Writing custom errors and the case of the nil error&lt;/li&gt;
&lt;li&gt;Stronger abstractions with small interfaces and using type assertions&lt;/li&gt;
&lt;li&gt;Customizing behavior by implementing interfaces in the standard library&lt;/li&gt;
&lt;li&gt;Reducing code size by using generics&lt;/li&gt;
&lt;li&gt;Going faster with CPU optimization&lt;/li&gt;
&lt;li&gt;Reducing memory usage&lt;/li&gt;
&lt;li&gt;Writing middleware for common tasks&lt;/li&gt;
&lt;li&gt;Advanced JSON serialization&lt;/li&gt;
&lt;li&gt;Streaming responses for large dynamic data&lt;/li&gt;
&lt;li&gt;Securing your server&lt;/li&gt;
&lt;li&gt;Utilizing workspaces to developing two dependant modules (such as application &amp;amp; logging library)&lt;/li&gt;
&lt;li&gt;Using build tags for platform dependent code&lt;/li&gt;
&lt;li&gt;Task automation with “go generate”, code that writes code&lt;/li&gt;
&lt;li&gt;Avoiding mocks by spinning services&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Practical Go for Developers</title><link>https://www.ardanlabs.com/team-live-training-courses/practical_go_for_developers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/practical_go_for_developers/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Practical Go for Developers training class helps experienced engineers get effective with the Go programming language and learn by writing code to solve common programming tasks.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Strings &amp;amp; formatted output&lt;/li&gt;
&lt;li&gt;Calling REST APIs&lt;/li&gt;
&lt;li&gt;Working with files&lt;/li&gt;
&lt;li&gt;Interfaces &amp;amp; Panics&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Catching panics&lt;/li&gt;
&lt;li&gt;Processing text&lt;/li&gt;
&lt;li&gt;Concurrency&lt;/li&gt;
&lt;li&gt;Distributing work&lt;/li&gt;
&lt;li&gt;Timeouts &amp;amp; cancellation&lt;/li&gt;
&lt;li&gt;Project Engineering&lt;/li&gt;
&lt;li&gt;Testing your code&lt;/li&gt;
&lt;li&gt;Structuring your code&lt;/li&gt;
&lt;li&gt;Writing an HTTP server&lt;/li&gt;
&lt;li&gt;Adding metrics &amp;amp; logging&lt;/li&gt;
&lt;li&gt;Configuration patterns&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Practical Go Foundations</title><link>https://www.ardanlabs.com/self-paced-courses/practical_go_foundations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/practical_go_foundations/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course will help you become familiar with the basic concepts of the Go programming language. Through lectures and coding exercises, you’ll learn about the core concepts needed to become a productive Go developer.&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Go Track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item><item><title>Practical Go Services</title><link>https://www.ardanlabs.com/team-live-training-courses/practical_go_services/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/practical_go_services/</guid><description>&lt;h3 id="course-description"&gt;Course Description:&lt;/h3&gt;
&lt;p&gt;This workshop is for Go developers who need to improve writing services and learn industry best practices. During this workshop we’ll develop a web service and implement the topics we discuss.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Writing a Web Service&lt;/li&gt;
&lt;li&gt;Storage &amp;amp; Health&lt;/li&gt;
&lt;li&gt;Testing &amp;amp; Performance&lt;/li&gt;
&lt;li&gt;Securing Your Application&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rust as a Service</title><link>https://www.ardanlabs.com/self-paced-courses/rust-as-a-service/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/rust-as-a-service/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course teaches integrating Rust into service-oriented architectures, covering REST server development, data handling, error management, and modularization. You&amp;rsquo;ll learn tracing, automated OpenAPI documentation, configuration for different environments, and alternative connectivity mechanisms like gRPC and WebSockets. Explore deploying a test service in a containerized environment, along with insights into service design, deployment strategies, and scaling. This prepares you for deploying high-performance Rust services in enterprise environments.&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Rust track. Not sold separately.&lt;/p&gt;</description></item><item><title>Rust as a Service</title><link>https://www.ardanlabs.com/team-live-training-courses/rust_as_a_service/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/rust_as_a_service/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course teaches integrating Rust into service-oriented architectures, covering REST server development, data handling, error management, and modularization. You&amp;rsquo;ll learn tracing, automated OpenAPI documentation, configuration for different environments, and alternative connectivity mechanisms like gRPC and WebSockets. Explore deploying a test service in a containerized environment, along with insights into service design, deployment strategies, and scaling. This prepares you for deploying high-performance Rust services in enterprise environments.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;details&gt;
 &lt;summary&gt;Introduction:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;1.0 - Introduction&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;REST Service:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;2.1 - Minimal HTTP Server&lt;/li&gt;
&lt;li&gt;2.2 - Service Stack&lt;/li&gt;
&lt;li&gt;2.3 - Extractors&lt;/li&gt;
&lt;li&gt;2.4 - Add a Simple Tower Layer (State)&lt;/li&gt;
&lt;li&gt;2.5 - Add a Simple Tower Layer (Mutable State)&lt;/li&gt;
&lt;li&gt;2.6 - Multiple States - Extension Layers&lt;/li&gt;
&lt;li&gt;2.7 - Quick Recap on State and Layers&lt;/li&gt;
&lt;li&gt;2.8 - Nesting Multiple Routers&lt;/li&gt;
&lt;li&gt;2.9 - Nested Routers with State&lt;/li&gt;
&lt;li&gt;2.10 - Calling Other Services&lt;/li&gt;
&lt;li&gt;2.11 - Returning Status Codes&lt;/li&gt;
&lt;li&gt;2.12 - Using IntoResponse&lt;/li&gt;
&lt;li&gt;2.13 - Error Handling with IntoResponse&lt;/li&gt;
&lt;li&gt;2.14 - Quick Recap on Nesting, Making Calls and Responses&lt;/li&gt;
&lt;li&gt;2.15 - Serving Static Content with Tower&lt;/li&gt;
&lt;li&gt;2.16 - Simple Header-Based Authentication&lt;/li&gt;
&lt;li&gt;2.17 - Simple Header-Based Auth with Middleware&lt;/li&gt;
&lt;li&gt;2.18 - Middleware Auth with Injection&lt;/li&gt;
&lt;li&gt;2.19 - Selectively Applying Layers&lt;/li&gt;
&lt;li&gt;2.20 - Router Layers&lt;/li&gt;
&lt;li&gt;2.21 - Layer Recap&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Tracing:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;3.1 - Minimal Example&lt;/li&gt;
&lt;li&gt;3.2 - Logging Axum/Tower&lt;/li&gt;
&lt;li&gt;3.3 - Timing Spans&lt;/li&gt;
&lt;li&gt;3.4 - Axum Spans&lt;/li&gt;
&lt;li&gt;3.5 - Logging to a File&lt;/li&gt;
&lt;li&gt;3.6 - Structured Logging to JSON&lt;/li&gt;
&lt;li&gt;3.7 - OpenTelemetry&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;OpenAPI Documentation:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;4.1 - OpenAPI Documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Handling Service Configuration:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;5.1 - Environment Variables with .env&lt;/li&gt;
&lt;li&gt;5.2 - The Config Crate - Basics&lt;/li&gt;
&lt;li&gt;5.3 - Loading Config via HTTP&lt;/li&gt;
&lt;li&gt;5.4 - CLI configuration with Clap&lt;/li&gt;
&lt;li&gt;5.5 - Recap&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Handling Service Configuration:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;6.1 - Hello Tonic - Protocol Definition&lt;/li&gt;
&lt;li&gt;6.2 - Hello Tonic - Project Definition and Build&lt;/li&gt;
&lt;li&gt;6.3 - Hello Tonic - The Server&lt;/li&gt;
&lt;li&gt;6.4 - Hello Tonic - The Client&lt;/li&gt;
&lt;li&gt;6.5 - gRPC Streaming&lt;/li&gt;
&lt;li&gt;6.6 - gRPC Streaming - Protocol Definition&lt;/li&gt;
&lt;li&gt;6.7 - gRPC Streaming - The Server&lt;/li&gt;
&lt;li&gt;6.8 - gRPC Streaming - The Client&lt;/li&gt;
&lt;li&gt;6.9 - Recap So Far&lt;/li&gt;
&lt;li&gt;6.10 - Authentication&lt;/li&gt;
&lt;li&gt;6.11 - Tracing&lt;/li&gt;
&lt;li&gt;6.12 - When to use gRPC&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Web Sockets:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;7.1 - Minimal Echo Server&lt;/li&gt;
&lt;li&gt;7.2 - A native WS client&lt;/li&gt;
&lt;li&gt;7.3 - JSON&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Service Deployment:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;8.1 - Test Service&lt;/li&gt;
&lt;li&gt;8.2 - Native Host Deployment&lt;/li&gt;
&lt;li&gt;8.3 - Docker Deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Service Design:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;9.1 - Understanding Your Company Architecture&lt;/li&gt;
&lt;li&gt;9.2 - Designing Individual Services&lt;/li&gt;
&lt;li&gt;9.3 - Combining Services into a Modular Monolith&lt;/li&gt;
&lt;li&gt;9.4 - Service Exposure&lt;/li&gt;
&lt;li&gt;9.5 - Scaling Out&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Wrap Up:&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;10.1 - Wrap Up&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;</description></item><item><title>Rust From C/C++</title><link>https://www.ardanlabs.com/self-paced-courses/rust-from-c/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/rust-from-c/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course bridges the transition from C and C++ to Rust by highlighting their similarities and differences. Exploring Rust&amp;rsquo;s native compilation, memory management, and advanced features, you&amp;rsquo;ll compare and contrast key concepts like types, control flow, and data structures in this class. Delve into Rust&amp;rsquo;s strengths in memory safety and concurrency, alongside its unified tool, Cargo, streamlining development. Additionally, learn how Rust facilitates interoperability with C and C++ through Foreign Function Interface (FFI).&lt;/p&gt;</description></item><item><title>Rust From C/C++</title><link>https://www.ardanlabs.com/team-live-training-courses/rust_from_c/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/rust_from_c/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course bridges the transition from C and C++ to Rust by highlighting their similarities and differences. Exploring Rust&amp;rsquo;s native compilation, memory management, and advanced features, you&amp;rsquo;ll compare and contrast key concepts like types, control flow, and data structures in this class. Delve into Rust&amp;rsquo;s strengths in memory safety and concurrency, alongside its unified tool, Cargo, streamlining development. Additionally, learn how Rust facilitates interoperability with C and C++ through Foreign Function Interface (FFI).&lt;/p&gt;</description></item><item><title>Rust, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/rust-k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/rust-k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Rust, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 75 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rust, Docker &amp; K8s Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/rust-k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/rust-k8s/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Includes All Rust, Docker &amp; K8’s Modules&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Self-Paced learning to fit your schedule&lt;/span&gt;
 &lt;/li&gt;
 &lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Learn everything you need to know with over 75 hours of material&lt;/span&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rust, Docker &amp; K8s Performance Bundle</title><link>https://www.ardanlabs.com/self-paced-individuals/performance-bundles/rust_k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-individuals/performance-bundles/rust_k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Rust, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 75 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Rust, Docker &amp; K8s Performance Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/performance-bundles/rust_k8s_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/performance-bundles/rust_k8s_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Includes All Rust, Docker &amp; K8’s Modules&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Self-Paced learning to fit your schedule&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Learn everything you need to know with over 75 hours of material&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Debugging</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_debugging/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_debugging/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course is designed for developers who want to become proficient debugging Go software using the Delve debugger. Whether you’ve never used a debugger in your life or are a Delve expert, everybody will walk away with new information that can be used in their day to day development workflow.&lt;/p&gt;
&lt;p&gt;The course will initially focus on Delve, which is the de facto Go debugger. We will start with the basics and move into more advanced use cases over the 5 days. On the last day of class, we will dig into new tools and cover profiling / perf tools, how to use them effectively, and how to interpret the data for root cause analysis.&lt;/p&gt;</description></item><item><title>Ultimate Go | Golang Training for Teams &amp; Individuals - Ardan Labs</title><link>https://www.ardanlabs.com/training/live/teams/ultimate-go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/live/teams/ultimate-go/</guid><description>&lt;ul class="flex flex-row flex-wrap gap-3"&gt;
 &lt;li class="badge shadow"&gt;Concurrency&lt;/li&gt;
 &lt;li class="badge shadow"&gt;JSON Web Tokens&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Polymorphism&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Security&lt;/li&gt;
 &lt;li class="badge shadow"&gt;gRPC&lt;/li&gt;
 &lt;li class="badge shadow"&gt;REST APIs&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Data Semantics&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Web Services&lt;/li&gt;
 &lt;li class="badge shadow"&gt;Decoupling&lt;/li&gt;
 &lt;li class="badge shadow"&gt;&amp; more&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go Bundle</title><link>https://www.ardanlabs.com/training/self-paced-training/go-bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced-training/go-bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Design Philosophies&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Syntax to Tooling&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Microservices&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Debugging&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/core-bundles/go_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/core-bundles/go_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Design Philosophies&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Syntax to Tooling&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Microservices&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Debugging&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/go/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Design Philosophies&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Syntax to Tooling&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Microservices&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Debugging&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/go/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Design Philosophies&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Syntax to Tooling&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Microservices&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Debugging&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go: Advanced Engineering</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_go_adv_engineering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_go_adv_engineering/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;From the beginning, you will pair program with the instructor, walking through the design philosophies and guidelines used to engineer the code. Throughout the class, you will learn more about Go and the advanced engineering features of the language.&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Go Track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item><item><title>Ultimate Go: Advanced Engineering</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_advanced_engineering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_advanced_engineering/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Ultimate Go Advanced Engineering class has been designed over the past year and will teach advanced Go concepts by building a reference implementation of a blockchain in Go! The goal of this class is to share how to code complex engineering tasks required to build a blockchain technology.&lt;/p&gt;
&lt;p&gt;From the beginning, you will pair-program with the instructor, walking through the design philosophies and guidelines used to engineer the code. Throughout the class, you will learn more about Go and the advanced engineering features of the language.&lt;/p&gt;</description></item><item><title>Ultimate Go: Language Guide</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_go/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Learn to write better, more idiomatic and performant code in Go with a focus on micro-level engineering decisions. The course begins with a focus on Go internals that are critical to understanding the core tradeoffs on readability, simplicity and performance.&lt;/p&gt;
&lt;p&gt;You will learn about data semantics, guidelines, mechanical sympathy, data oriented design, package oriented design, and how to structure your Go projects for the long term.&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Go Track. Not sold separately.&lt;/p&gt;</description></item><item><title>Ultimate Go: Language Guide</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_classic/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_classic/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Ultimate Go: Language Guide has been designed over the past 8 years and goes beyond just being a Go language class. There will be very little time spent on specific Go syntax. Our time will be spent learning how to read and comprehend Go code with a big focus on “if performance matters” then these things matter.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data-Oriented Design&lt;/li&gt;
&lt;li&gt;Memory Semantics and Allocations&lt;/li&gt;
&lt;li&gt;Mechanical Sympathy with Hardware and Runtime&lt;/li&gt;
&lt;li&gt;Data Semantics&lt;/li&gt;
&lt;li&gt;Polymorphism with Interfaces&lt;/li&gt;
&lt;li&gt;Decoupling Mechanics / Semantics&lt;/li&gt;
&lt;li&gt;Compositional Design&lt;/li&gt;
&lt;li&gt;Scheduler Semantics&lt;/li&gt;
&lt;li&gt;Goroutines&lt;/li&gt;
&lt;li&gt;Data Races&lt;/li&gt;
&lt;li&gt;Synchronization / Orchestration&lt;/li&gt;
&lt;li&gt;CPU and Memory Profiling&lt;/li&gt;
&lt;li&gt;Tracing Programs&lt;/li&gt;
&lt;li&gt;Micro/Macro level profiling&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Go: Notebook</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate-go-notebook/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate-go-notebook/</guid><description>&lt;h3 id="about-this-book"&gt;About This Book&lt;/h3&gt;
&lt;p&gt;This notebook has been written and designed to provide a reference to everything covered in our Ultimate Go class. If you have taken the class before, this notebook will be invaluable for reminders on the content. If you have never taken the class, there is still tremendous value in this book. It covers more advanced topics not found in other books today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Guidelines, design philosophy, white-boarding, and notes shared from the Ultimate Go training.&lt;/li&gt;
&lt;li&gt;Learn advanced concepts in Go from types to profiling.&lt;/li&gt;
&lt;li&gt;Get started with generic functions and types.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="btn btn-neutral btn-outline rounded-xl" href="https://www.ardanlabs.com/ultimate-go-notebook"&gt;View the full details&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Ultimate Go: Software Design with Kubernetes</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_service/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_service/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;From the beginning of the course, you will pair-program with your instructor Bill Kennedy as he walks you through the design philosophies, architectural decisions, and best practices as they apply to engineering a production-ready Go service.&lt;/p&gt;
&lt;p&gt;With each new feature that is added to the service, you will learn how to deploy and manage the Kubernetes environment used to run the service. Throughout the class, the code being worked on is pushed to a repository for personal access and review.&lt;/p&gt;</description></item><item><title>Ultimate Go: Software Design with Kubernetes</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_service_with_kubernetes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_go_service_with_kubernetes/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;From the beginning of the course, you will pair-program with your instructor Bill Kennedy as he walks you through the design philosophies, architectural decisions, and best practices as they apply to engineering a production-ready Go service.&lt;/p&gt;
&lt;p&gt;With each new feature that is added to the service, you will learn how to deploy and manage the Kubernetes environment used to run the service. Throughout the class, the code being worked on is pushed to a repository for personal access and review.&lt;/p&gt;</description></item><item><title>Ultimate Rust 2: Intermediate Concepts</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_intermediate_concepts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_intermediate_concepts/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;p&gt;This is a hands-on course! Not only are there targeted exercises for each topic discussed, there are also a series of project scenarios that walk you through using what you&amp;rsquo;ve learned to put together playable game prototypes that work on macOS, Linux, and Windows.&lt;/p&gt;
&lt;p&gt;These projects will make use of Rusty Engine, a game engine developed specifically for this course to keep game engine concepts to a minimum so you can focus on using exactly what you learned in this course.&lt;/p&gt;</description></item><item><title>Ultimate Rust Best Practices</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_best_practices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_best_practices/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course covers many best practices to help you with integrate Rust into your workflow, and let Rust’s tooling work for you. It includes formatting, linting, dependencies, vulnerabilities, code style and general development advice.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Section 1: Tooling&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;1.0 - Introduction - Formatting&lt;/li&gt;
&lt;li&gt;1.1 - Clippy (the linter)&lt;/li&gt;
&lt;li&gt;1.2 - Documentation&lt;/li&gt;
&lt;li&gt;1.3 - Understanding Dependencies&lt;/li&gt;
&lt;li&gt;1.4 - Managing Your Own Dependencies&lt;/li&gt;
&lt;li&gt;1.5 - Checking for Vulnerabilities&lt;/li&gt;
&lt;li&gt;1.6 - Check for Outdated Dependencies&lt;/li&gt;
&lt;li&gt;1.7 - Denying Dependencies by Licensing&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Section 2 : Code Best Practices&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;2.0 - Favor Iterators&lt;/li&gt;
&lt;li&gt;2.1 - Minimize Cloning (we have an alternative name as well Cloning Can Be a Code Smell)&lt;/li&gt;
&lt;li&gt;2.2 - Don’t Emulate OOP&lt;/li&gt;
&lt;li&gt;2.3 - Favor Small Functions&lt;/li&gt;
&lt;li&gt;2.4 - Clever Code&lt;/li&gt;
&lt;li&gt;2.5 - Floating Point Numbers&lt;/li&gt;
&lt;li&gt;2.6 - Platform &amp;amp; Feature Specific Code&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Section 3 : General Best Practices&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;3.0 - TANSTAAFL (There Ain’t No Such Thing As A Free Lunch)&lt;/li&gt;
&lt;li&gt;3.1 - YAGNI : You Ain’t Gonna Need It&lt;/li&gt;
&lt;li&gt;3.2 - Domain Boundaries&lt;/li&gt;
&lt;li&gt;3.3 - Taming Compile Times&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Ultimate Rust Bundle</title><link>https://www.ardanlabs.com/self-paced-individuals/core-bundles/rust_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-individuals/core-bundles/rust_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Getting Started with Rust&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Fearless System Thread Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Async/Await Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Memory &amp; Resource Management&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Build a Network Service&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust Bundle</title><link>https://www.ardanlabs.com/self-paced-teams/core-bundles/rust_bundle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-teams/core-bundles/rust_bundle/</guid><description>&lt;ul&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Getting Started with Rust&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Fearless System Thread Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Async/Await Concurrency&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Memory &amp; Resource Management&lt;/li&gt;
 &lt;li&gt;&lt;i class="fa fa-check" aria-hidden="true"&gt;&lt;/i&gt; Build a Network Service&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/individuals/bundles/rust/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/individuals/bundles/rust/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Getting Started with Rust&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Fearless System Thread Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Async/Await Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Memory &amp; Resource Management&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Build a Network Service&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust Bundle | Ardan Labs</title><link>https://www.ardanlabs.com/training/self-paced/team/bundles/rust/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/training/self-paced/team/bundles/rust/</guid><description>&lt;ul class="bg-base-100 rounded-xl flex flex-col gap-2 py-4 px-4 text-lg text-left border"&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Getting Started with Rust&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Fearless System Thread Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Async/Await Concurrency&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Memory &amp; Resource Management&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
 &lt;svg class="text-success inline-block h-7 pr-2" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;&lt;/svg&gt;
 &lt;span&gt;Build a Network Service&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust Foundations</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate-rust-foundations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate-rust-foundations/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Ultimate Rust: This course covers many best practices to help you with integrate Rust into your workflow, and let Rust’s tooling work for you. It includes formatting, linting, dependencies, vulnerabilities, code style and general development advice..&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Rust track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item><item><title>Ultimate Rust: Crash Course</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_crash_course/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_crash_course/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;h3 id="what-youll-learn"&gt;What you’ll learn:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Rust language basics, tooling, and ecosystem&lt;/li&gt;
&lt;li&gt;Fundamentals such as variables, scope, functions, modules, scalar &amp;amp; compound types, control flow, strings, structs, traits, enums, and more.&lt;/li&gt;
&lt;li&gt;Fun tips &amp;amp; tricks for using Rust and systems programming in general&lt;/li&gt;
&lt;li&gt;Concepts essential to understanding Rust such as ownership, references &amp;amp; borrowing, the memory model, and why Rust focuses on safety, concurrency, and speed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="requirements"&gt;Requirements:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A basic understanding of general programming concepts&lt;/li&gt;
&lt;li&gt;Familiarity with other programming languages such as Python, C, etc. is helpful, but not required.&lt;/li&gt;
&lt;li&gt;Rust installed and ready to use - you&amp;rsquo;ll learn more by doing the exercises!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="who-this-course-is-for"&gt;Who this course is for:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Aspiring systems programmers, software developers, engineers, wizards, warriors, and hobbits&lt;/li&gt;
&lt;li&gt;Any developer who needs to run code fast, efficiently, securely, under tight restraints, or with a minimum of bugs&lt;/li&gt;
&lt;li&gt;A desire to begin using Rust&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Module 1: Introduction&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Lesson 1.1 - Introduction&lt;/li&gt;
&lt;li&gt;Lesson 1.2 - Exercises Overview&lt;/li&gt;
&lt;li&gt;Lesson 1.3 - Installation&lt;/li&gt;
&lt;li&gt;Lesson 1.4 - Editor/IDE&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Module 2: Fundamentals&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Lesson 2.1 - Cargo&lt;/li&gt;
&lt;li&gt;Lesson 2.2 - Variables&lt;/li&gt;
&lt;li&gt;Lesson 2.3 - Scope&lt;/li&gt;
&lt;li&gt;Lesson 2.4 - Memory Safety&lt;/li&gt;
&lt;li&gt;Lesson 2.5 - Exercise A - Variables&lt;/li&gt;
&lt;li&gt;Lesson 2.6 - Functions&lt;/li&gt;
&lt;li&gt;Lesson 2.7 - Exercise B - Functions&lt;/li&gt;
&lt;li&gt;Lesson 2.8 - Module System&lt;/li&gt;
&lt;li&gt;Lesson 2.9 - Exercise C - Module System&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Module 3: Primitive Types &amp; Control Flow&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Lesson 3.1 - Scalar Types&lt;/li&gt;
&lt;li&gt;Lesson 3.2 - Compound Types&lt;/li&gt;
&lt;li&gt;Lesson 3.3 - Exercise D - Simple Types&lt;/li&gt;
&lt;li&gt;Lesson 3.4 - Control Flow&lt;/li&gt;
&lt;li&gt;Lesson 3.5 - Exercise E - Control Flow&lt;/li&gt;
&lt;li&gt;Lesson 3.6 - Strings&lt;/li&gt;
&lt;li&gt;Lesson 3.7 - String Literals&lt;/li&gt;
&lt;li&gt;Lesson 3.8 - Exercise F - Strings&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Module 4: The Heart of Rust&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Lesson 4.1 - Ownership&lt;/li&gt;
&lt;li&gt;Lesson 4.2 - References &amp;amp; Borrowing&lt;/li&gt;
&lt;li&gt;Lesson 4.3 - Exercise G - Ownership &amp;amp; References&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;details&gt;
 &lt;summary&gt;Module 5: The Meat of Rust&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Lesson 5.1 - Structs&lt;/li&gt;
&lt;li&gt;Lesson 5.2 - Exercise H - Structs&lt;/li&gt;
&lt;li&gt;Lesson 5.3 - Traits&lt;/li&gt;
&lt;li&gt;Lesson 5.4 - Exercise I - Traits&lt;/li&gt;
&lt;li&gt;Lesson 5.5 - Collections&lt;/li&gt;
&lt;li&gt;Lesson 5.6 - Exercise J - Collections&lt;/li&gt;
&lt;li&gt;Lesson 5.7 - Enums&lt;/li&gt;
&lt;li&gt;Lesson 5.8 - Exercise K - Enums&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Ultimate Rust: Foundations</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_foundations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_foundations/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Ultimate Rust Foundations class starts with an introduction to Rust, and why you benefit from using – both as a foundation, and within your existing ecosystem.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Rust includes Cargo, a swiss-army knife tool that can:&lt;/li&gt;
&lt;li&gt;Using Rust without Cargo&lt;/li&gt;
&lt;li&gt;Rust’s Safety Guarantees&lt;/li&gt;
&lt;li&gt;“Hello World” application – the foundation of most languages.&lt;/li&gt;
&lt;li&gt;Arrays, vectors and slices.&lt;/li&gt;
&lt;li&gt;Strict types and strong typing.&lt;/li&gt;
&lt;li&gt;Serializing and De-Serializing data.&lt;/li&gt;
&lt;li&gt;Iterative Programming – using iterators to combine operations.&lt;/li&gt;
&lt;li&gt;Working with Strings&lt;/li&gt;
&lt;li&gt;Protection from data races&lt;/li&gt;
&lt;li&gt;Easy multi-threaded concurrency with Rayon&lt;/li&gt;
&lt;li&gt;Ultimate control with raw threads&lt;/li&gt;
&lt;li&gt;High-performance Input/Output with Asynchronous design and Tokio.&lt;/li&gt;
&lt;li&gt;Build a CPU bound program with Rayon, and use all of your CPU power.&lt;/li&gt;
&lt;li&gt;Manage raw-threads and shared data.&lt;/li&gt;
&lt;li&gt;Spin up a simple server in 10 minutes.&lt;/li&gt;
&lt;li&gt;The classic Object-Oriented Programming example of different objects printing different text – but with traits.&lt;/li&gt;
&lt;li&gt;Designing a simple generic function with ToString.&lt;/li&gt;
&lt;li&gt;Stacked traits – traits that depend upon one another, combined with generic programming.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust: Foundations - Next Steps</title><link>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_next_steps/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/ultimate_rust_next_steps/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;This course offers the next steps not covered in Ultimate Rust: Foundations that expands on and optimizes what you&amp;rsquo;ve already built.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;hr&gt;
&lt;div class="grid grid-cols-1 gap-1"&gt;
&lt;div class="flex flex-col gap-2"&gt;
&lt;details&gt;
 &lt;summary&gt;Ultimate Rust: Foundations - Next Steps&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;1.0 - Bi-Directional Communication&lt;/li&gt;
&lt;li&gt;1.2 - Sending Commands &amp;amp; Prevent Unbounded Growth&lt;/li&gt;
&lt;li&gt;1.3 - Giving the Collector a Diet&lt;/li&gt;
&lt;li&gt;1.4 - Giving the Collector a Diet (Cont)&lt;/li&gt;
&lt;li&gt;1.5 - Optimizing File Reading &amp;amp; Adapting Files In Flight&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Ultimate Rust: Integrating Pipelines</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_integrating_pipelines/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_integrating_pipelines/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;Rust doesn’t have to be an all or nothing proposition. Rust is very good at sliding into an existing platform, allowing you to focus on optimizing – both for speed and safety – the parts that matter without throwing away all of your existing hard work.&lt;/p&gt;
&lt;h3 id="course-outline"&gt;Course Outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Introducing FFI, the Foreign Function Interface.&lt;/li&gt;
&lt;li&gt;Consuming a C library from Rust:&lt;/li&gt;
&lt;li&gt;From C to Rust:&lt;/li&gt;
&lt;li&gt;Calling Go from Rust&lt;/li&gt;
&lt;li&gt;Building a Rust FFI Crate&lt;/li&gt;
&lt;li&gt;Consume the Rust crate from C&lt;/li&gt;
&lt;li&gt;Consume the Rust crate from Go&lt;/li&gt;
&lt;li&gt;Managing Your Build Process – Practical Observations&lt;/li&gt;
&lt;li&gt;Porting Parts to Rust&lt;/li&gt;
&lt;li&gt;Build an HTTP authentication service with Actix in under 200 lines of Rust.&lt;/li&gt;
&lt;li&gt;Build an efficient, binary protocol server with Tokio.&lt;/li&gt;
&lt;li&gt;Combining asynchronous high-performance I/O with CPU-bound computation.&lt;/li&gt;
&lt;li&gt;Event tracing&lt;/li&gt;
&lt;li&gt;Use a Unikernel to host a Rust service as a single-purpose virtual machine.&lt;/li&gt;
&lt;li&gt;Use WebAssembly (WASM) to host high-performance code in the browser.&lt;/li&gt;
&lt;li&gt;Build without a standard library for embedded targets&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ultimate Rust: Optimizing Rust &amp; Debugging</title><link>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_optimizing_and_debug/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/team-live-training-courses/ultimate_rust_optimizing_and_debug/</guid><description>&lt;h3 id="course-description"&gt;Course Description&lt;/h3&gt;
&lt;p&gt;The Rust compiler catches many bugs for you that are common in other languages. Use the tools to avoid bugs and use Rust’s error system to pass meaningful errors and handle them appropriately.&lt;/p&gt;
&lt;h3 id="optimizing-rust"&gt;Optimizing Rust&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Measure First: the importance of knowing what to optimize&lt;/li&gt;
&lt;li&gt;Use Rust’s built-in benchmark system to test component performance.&lt;/li&gt;
&lt;li&gt;Use a Profiler to find hotspots.&lt;/li&gt;
&lt;li&gt;When NOT to optimize&lt;/li&gt;
&lt;li&gt;Optimize the Algorithm First&lt;/li&gt;
&lt;li&gt;Optimization levels, Safety, Link Time Optimization.&lt;/li&gt;
&lt;li&gt;Understanding your cache: When Optimizing for Size is faster than Optimizing for Speed.&lt;/li&gt;
&lt;li&gt;Using unsafe safely.&lt;/li&gt;
&lt;li&gt;Profile-Guided Optimization.&lt;/li&gt;
&lt;li&gt;Compiler hints and inlining.&lt;/li&gt;
&lt;li&gt;Tracing distributed components&lt;/li&gt;
&lt;li&gt;Is your microservice too micro?&lt;/li&gt;
&lt;li&gt;Blocking Operations&lt;/li&gt;
&lt;li&gt;Waiting for Databases, File and Network I/O&lt;/li&gt;
&lt;li&gt;Fast, Efficient Logging&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="debugging-rust"&gt;Debugging Rust&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Using your tools&lt;/li&gt;
&lt;li&gt;Debugging with println statements.&lt;/li&gt;
&lt;li&gt;Faster printing: tracing with tokio, and fast logging.&lt;/li&gt;
&lt;li&gt;Types of bug&lt;/li&gt;
&lt;li&gt;Attaching a debugger&lt;/li&gt;
&lt;li&gt;Unit testing to avoid bugs in the first place.&lt;/li&gt;
&lt;li&gt;Use Rust’s error system to pass meaningful errors—-and handle them appropriately.&lt;/li&gt;
&lt;li&gt;Avoiding Bugs with the Rust Type System.&lt;/li&gt;
&lt;li&gt;Strong Types, compile-time checking.&lt;/li&gt;
&lt;li&gt;Strong Types, run-time checking.&lt;/li&gt;
&lt;li&gt;Floating point errors.&lt;/li&gt;
&lt;li&gt;Unicode errors.&lt;/li&gt;
&lt;li&gt;Type-conversion errors.&lt;/li&gt;
&lt;li&gt;Always test in debug mode to catch overflow and out-of-bounds errors.&lt;/li&gt;
&lt;li&gt;Memory Issues&lt;/li&gt;
&lt;li&gt;Great Documentation with Rust.&lt;/li&gt;
&lt;li&gt;Integration testing with library examples.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Writing Secure Go Code</title><link>https://www.ardanlabs.com/self-paced-courses/writing_secure_go_code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.ardanlabs.com/self-paced-courses/writing_secure_go_code/</guid><description>&lt;h3 id="course-introduction"&gt;Course Introduction&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Follow along with the instructor as he overviews common vulnerabilities in a live Go application. You’ll learn about tools and strategies to help you identify security vulnerabilities and how to think about security when it comes to your Golang application.&lt;/p&gt;
&lt;p&gt;This course is part of the Ultimate Go Track. Not sold separately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; All of our bundles are for a one-year subscription.&lt;/p&gt;
&lt;p&gt;At the end of the subscription period, your membership does &lt;b&gt;not automatically renew&lt;/b&gt;.&lt;/p&gt;</description></item></channel></rss>