<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Languages on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/</link><description>Recent content in Languages on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/index.xml" rel="self" type="application/rss+xml"/><item><title>JVM Languages</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/jvm/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/jvm/</guid><description>&lt;p&gt;JVM-hosted languages beyond Java. Each trades something to gain something, and each found a niche where the trade made sense.&lt;/p&gt;
&lt;p&gt;Java was enough. It still is. The honest reason to know Groovy, Scala, and Kotlin is not that they are better — it is that the ecosystem puts them in front of you whether you choose them or not. Build tools, CI pipelines, and frameworks make that decision for you.&lt;/p&gt;
&lt;p&gt;A practical tell: if the Java code you are reading starts to feel syntactically off — closures where you did not expect them, type inference that seems too aggressive, operators that should not be there — you are probably looking at Groovy, Scala, or Kotlin. Worth knowing enough to recognise each and get things done.&lt;/p&gt;
&lt;p&gt;Also worth noting: Java itself has been catching up fast. Virtual threads, records, sealed classes, pattern matching, a faster release cadence — the gap between &amp;ldquo;Java&amp;rdquo; and &amp;ldquo;a more modern JVM language&amp;rdquo; has narrowed considerably. The case for leaving Java for something else on the JVM is weaker now than it was five years ago.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="groovy"&gt;Groovy
&lt;/h2&gt;&lt;p&gt;Dynamic, optionally typed JVM language with a syntax that is a superset of Java. Groovy code is often valid Java. The dynamic parts — closures, metaprogramming, GStrings — are what made it popular as a scripting and DSL language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where you find it today:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gradle build scripts&lt;/strong&gt;: the Groovy DSL is the original Gradle scripting language (now being replaced by Kotlin DSL)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jenkins pipelines&lt;/strong&gt;: Groovy is the language of Jenkinsfile declarative and scripted pipelines&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spock framework&lt;/strong&gt;: expressive BDD-style testing for JVM projects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Groovy&amp;rsquo;s peak was the early Gradle/Jenkins era. Kotlin has taken over most of the &amp;ldquo;better Java scripting&amp;rdquo; use cases. Still found widely in CI/CD tooling — if you work with Jenkins or older Gradle builds, you will write Groovy.&lt;/p&gt;
&lt;p&gt;Groovy shows up in Gradle builds and Jenkins pipelines. Know enough to read and modify it; not a reason to seek it out.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="scala"&gt;Scala
&lt;/h2&gt;&lt;p&gt;Statically typed functional + OOP hybrid on the JVM. Strong type system, pattern matching, immutable data by default. Compiles to JVM bytecode and interops with Java libraries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where you find it today:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Apache Spark&lt;/strong&gt;: the dominant big data / data engineering platform is written in Scala and has a native Scala API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Akka&lt;/strong&gt;: actor model concurrency framework&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Play Framework&lt;/strong&gt;: web framework, less common now&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SBT&lt;/strong&gt;: build tool, build definition is Scala code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scala has a reputation for complexity and a steep learning curve. The community split between Scala 2 and Scala 3 (Dotty) added friction. If you are working with Spark, you will encounter Scala. If you are not, the reasons to choose it over Kotlin or Java are narrower than they used to be. Another case where Java catching up makes the trade less obvious.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kotlin"&gt;Kotlin
&lt;/h2&gt;&lt;p&gt;JetBrains&amp;rsquo; answer to Java&amp;rsquo;s verbosity. Statically typed, concise, null-safe by design. Full Java interop — Kotlin and Java can call each other in the same project. Official Android development language since 2017.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where you find it today:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android development (the default)&lt;/li&gt;
&lt;li&gt;Spring Boot (first-class support since Spring 5)&lt;/li&gt;
&lt;li&gt;Gradle Kotlin DSL (replacing Groovy as the recommended build script language)&lt;/li&gt;
&lt;li&gt;Ktor — Kotlin-native web framework from JetBrains&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kotlin is what you reach for when you want Java but less of it. Coroutines handle async cleanly. The Kotlin DSL in Gradle gives type safety that the Groovy DSL could not.&lt;/p&gt;
&lt;p&gt;Kotlin is the cleanest of the JVM alternatives — but again, Java has been closing the gap. Worth knowing if the project is already Kotlin; not a compelling reason to switch from Java.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="jython"&gt;Jython
&lt;/h2&gt;&lt;p&gt;Python running on the JVM. Jython implements the Python language but executes on the JVM, meaning Python code can import and use Java classes directly.&lt;/p&gt;
&lt;p&gt;Worth knowing it exists. In practice: Jython implements Python 2 (Python 3 support was never completed), which limits its relevance post-2020. Main use case was embedding Python scripting in Java applications. A few enterprise tools and test frameworks still use it.&lt;/p&gt;
&lt;p&gt;If you need Python-JVM interop today, consider alternatives: GraalVM&amp;rsquo;s polyglot API, or just making an HTTP boundary between a Python service and the JVM service.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>Rust</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/rust/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/rust/</guid><description>&lt;p&gt;Systems language with memory safety guarantees without a garbage collector. The ownership and borrow checker model enforces at compile time what other languages leave to the runtime or the programmer.&lt;/p&gt;
&lt;p&gt;The pitch: C/C++ performance and control, without the entire class of memory safety bugs that makes systems programming treacherous. In practice the borrow checker is the learning curve, it rejects code that would be valid in any other language until you understand why it is wrong.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="where-rust-is-winning"&gt;Where Rust is winning
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CLI tooling&lt;/strong&gt;: a significant share of modern CLI tools are written in Rust. &lt;code&gt;ripgrep&lt;/code&gt;, &lt;code&gt;fd&lt;/code&gt;, &lt;code&gt;bat&lt;/code&gt;, &lt;code&gt;exa&lt;/code&gt;/&lt;code&gt;eza&lt;/code&gt;, &lt;code&gt;zoxide&lt;/code&gt;, &lt;code&gt;tokei&lt;/code&gt;. Startup time and binary distribution (single static binary) are the wins.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WebAssembly&lt;/strong&gt;: Rust compiles to WASM with first-class tooling (&lt;code&gt;wasm-pack&lt;/code&gt;, &lt;code&gt;wasm-bindgen&lt;/code&gt;). Running near-native code in the browser or at the edge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Embedded / systems&lt;/strong&gt;: where C used to be the only option. The safety guarantees matter more, not less, when there is no OS underneath.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloud infrastructure tooling&lt;/strong&gt;: parts of the ecosystem are being rewritten in Rust. Firecracker (AWS Lambda&amp;rsquo;s VMM), parts of the Linux kernel, Cloudflare Workers runtime.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Cargo&lt;/strong&gt;: the build system and package manager. Handles dependencies, building, testing, and publishing. One of the better-designed package managers in any ecosystem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;rustup&lt;/strong&gt;: toolchain manager. Manages Rust versions and targets (cross-compilation).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;clippy&lt;/strong&gt;: linter. Catches more than the compiler, opinionated in useful ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;rustfmt&lt;/strong&gt;: formatter. Like &lt;code&gt;gofmt&lt;/code&gt;, one style, no debate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; VS Code with &lt;code&gt;rust-analyzer&lt;/code&gt; extension, or IntelliJ/CLion with the Rust plugin.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-learning-curve"&gt;The learning curve
&lt;/h2&gt;&lt;p&gt;The borrow checker is a genuine obstacle. Rust enforces at compile time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exactly one owner of any value&lt;/li&gt;
&lt;li&gt;Any number of immutable references OR one mutable reference — not both&lt;/li&gt;
&lt;li&gt;References cannot outlive the value they point to&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is unfamiliar to anyone coming from languages with a GC. The compiler error messages are unusually helpful, but expect to spend real time understanding ownership before writing idiomatic Rust.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://doc.rust-lang.org/book/" target="_blank" rel="noopener"
 &gt;The Rust Book&lt;/a&gt;: the standard introduction, free online&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rust-lang/rustlings" target="_blank" rel="noopener"
 &gt;Rustlings&lt;/a&gt;: small exercises for learning by doing&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crates.io/" target="_blank" rel="noopener"
 &gt;crates.io&lt;/a&gt;: the package registry&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blessed.rs/" target="_blank" rel="noopener"
 &gt;Blessed.rs&lt;/a&gt;: curated crate recommendations by category&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-trend-pattern"&gt;The trend pattern
&lt;/h2&gt;&lt;p&gt;Language adoption tends to follow ecosystem trends rather than purely technical merit. I started with Java. Then OpenStack brought Python into infrastructure work. Then Kubernetes arrived and its ecosystem was written in Go — so Go became the language of the cloud-native world by proximity as much as by choice.&lt;/p&gt;
&lt;p&gt;Rust looks like the next turn of that cycle. The &amp;ldquo;rewrite it in Rust&amp;rdquo; trend is real and growing — CLI tooling, parts of the Linux kernel, browser engines, cloud infrastructure. If the pattern holds, the ecosystem will pull Rust into more places where it becomes the pragmatic choice rather than the deliberate one.&lt;/p&gt;
&lt;p&gt;Haven&amp;rsquo;t given it a serious attempt yet. Worth doing — not because Rust is clearly the right tool for the things currently being built, but because being ahead of the ecosystem trend rather than behind it is how you end up with useful experience when the moment arrives. The tooling is good, the learning resources are good, and the borrow checker will teach you something about memory regardless of whether you end up writing Rust in production.&lt;/p&gt;</description></item><item><title>Bash</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/bash/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/bash/</guid><description>&lt;p&gt;Bash is unavoidable in DevOps work — CI/CD pipelines, container entrypoints, system init scripts, and quick automation all end up as shell scripts eventually. Knowing how to write it well saves a lot of pain.&lt;/p&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://www.shellcheck.net/" target="_blank" rel="noopener"
 &gt;ShellCheck&lt;/a&gt;: catches common mistakes and anti-patterns. Run it in CI, or install the IDE plugin. Most of what it flags is genuinely wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; Any editor works. ShellCheck integrations exist for VS Code, IntelliJ, Vim, and most others.&lt;/p&gt;
&lt;h2 id="good-habits"&gt;Good habits
&lt;/h2&gt;&lt;p&gt;Set these at the top of every non-trivial script:&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; — exit on error&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; — error on unset variables&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o pipefail&lt;/code&gt;: catch errors in pipes, not just the last command&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use &lt;code&gt;shellcheck&lt;/code&gt; before committing. Most Bash bugs it catches are subtle and only surface under specific conditions in production.&lt;/p&gt;
&lt;h2 id="when-to-reach-for-python-instead"&gt;When to reach for Python instead
&lt;/h2&gt;&lt;p&gt;When the script grows beyond ~50 lines, needs associative arrays, JSON parsing, or HTTP calls — switch to Python. Bash is great glue; it&amp;rsquo;s a poor application language.&lt;/p&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.shellcheck.net/" target="_blank" rel="noopener"
 &gt;ShellCheck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.gnu.org/software/bash/manual/" target="_blank" rel="noopener"
 &gt;Bash Reference Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://google.github.io/styleguide/shellguide.html" target="_blank" rel="noopener"
 &gt;Google Shell Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/golang/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/golang/</guid><description>&lt;p&gt;Go is my go-to language for backend services, CLI tools, and DevOps tooling. The standard library covers most of what you need, the compiler is fast, and the concurrency model (goroutines + channels) makes it well suited for infrastructure-adjacent work.&lt;/p&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; &lt;a class="link" href="https://www.jetbrains.com/go/" target="_blank" rel="noopener"
 &gt;GoLand&lt;/a&gt;: JetBrains&amp;rsquo; Go-specific IDE. Solid refactoring, built-in debugger, good test runner integration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formatting:&lt;/strong&gt; &lt;code&gt;gofmt&lt;/code&gt; / &lt;code&gt;goimports&lt;/code&gt;: no debates about style, just run it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://golangci-lint.run/" target="_blank" rel="noopener"
 &gt;golangci-lint&lt;/a&gt;: meta-linter that runs a configurable set of linters in one pass. Worth wiring into CI.&lt;/p&gt;
&lt;h2 id="testing"&gt;Testing
&lt;/h2&gt;&lt;p&gt;Testing is built into the standard library — &lt;code&gt;go test ./...&lt;/code&gt; is all you need to get started. Table-driven tests are the idiomatic pattern for covering multiple cases cleanly.&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:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestAdd&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;testing&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cases&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt;{ &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;want&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; }{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&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:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cases&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;); &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;want&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Errorf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Add(%d, %d) = %d, want %d&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;want&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://go.dev/" target="_blank" rel="noopener"
 &gt;go.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://go.dev/doc/effective_go" target="_blank" rel="noopener"
 &gt;Effective Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gobyexample.com/" target="_blank" rel="noopener"
 &gt;Go by Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Java</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/java/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/java/</guid><description>&lt;p&gt;Java is my primary language for backend services. Mature ecosystem, strong tooling, and frameworks like Spring Boot and Quarkus make it productive for building production-grade APIs and microservices.&lt;/p&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; &lt;a class="link" href="https://www.jetbrains.com/idea/" target="_blank" rel="noopener"
 &gt;IntelliJ IDEA&lt;/a&gt; — the standard for Java development. Excellent refactoring, code analysis, and framework support (Spring, Quarkus, Jakarta EE). The free Community edition covers most needs; Ultimate adds Spring-specific tooling and database tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build:&lt;/strong&gt; &lt;a class="link" href="https://gradle.org/" target="_blank" rel="noopener"
 &gt;Gradle&lt;/a&gt; or &lt;a class="link" href="https://maven.apache.org/" target="_blank" rel="noopener"
 &gt;Maven&lt;/a&gt; — Gradle is the least bad option; keep the build file focused on compile, test, and package only. See &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/cicd/build-systems/" &gt;Build Systems&lt;/a&gt; for the full take.&lt;/p&gt;
&lt;h2 id="frameworks"&gt;Frameworks
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://spring.io/projects/spring-boot" target="_blank" rel="noopener"
 &gt;Spring Boot&lt;/a&gt; — the dominant choice for enterprise Java. Convention over configuration, huge ecosystem, production-ready out of the box.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://quarkus.io/" target="_blank" rel="noopener"
 &gt;Quarkus&lt;/a&gt; — optimized for containers and GraalVM native compilation. Noticeably faster startup and lower memory footprint than Spring Boot. Worth considering for microservices running in Kubernetes.&lt;/p&gt;
&lt;h2 id="testing-with-junit"&gt;Testing with JUnit
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://junit.org/junit5/" target="_blank" rel="noopener"
 &gt;JUnit 5&lt;/a&gt; is the standard testing framework. Combine with &lt;a class="link" href="https://site.mockito.org/" target="_blank" rel="noopener"
 &gt;Mockito&lt;/a&gt; for mocking and &lt;a class="link" href="https://assertj.github.io/doc/" target="_blank" rel="noopener"
 &gt;AssertJ&lt;/a&gt; for readable assertions.&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-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;shouldReturnGreeting&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; service &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; GreetingService();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; assertThat(service.&lt;span style="color:#a6e22e"&gt;greet&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Manfred&amp;#34;&lt;/span&gt;)).&lt;span style="color:#a6e22e"&gt;isEqualTo&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Hello, Manfred&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Spring Boot&amp;rsquo;s &lt;code&gt;@SpringBootTest&lt;/code&gt; and &lt;code&gt;@WebMvcTest&lt;/code&gt; slice annotations make integration testing straightforward without spinning up a full application context.&lt;/p&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.spring.io/spring-boot/index.html" target="_blank" rel="noopener"
 &gt;docs.spring.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://quarkus.io/guides/" target="_blank" rel="noopener"
 &gt;quarkus.io/guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://junit.org/junit5/docs/current/user-guide/" target="_blank" rel="noopener"
 &gt;JUnit 5 docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Python</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/python/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/python/</guid><description>&lt;p&gt;Python is my scripting and automation language of choice. I reach for it when Bash starts getting unwieldy — data processing, API interactions, infrastructure automation scripts, and one-off tooling.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;2024 note:&lt;/strong&gt; For anything beyond quick scripts I&amp;rsquo;m increasingly reaching for Go instead. Better performance, a single compiled binary, and stronger typing make Go a more honest choice for tools that end up running in production. Python still wins for data work and anything where the ecosystem matters (ML, pandas, etc.).&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; &lt;a class="link" href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener"
 &gt;PyCharm&lt;/a&gt;: JetBrains&amp;rsquo; Python IDE. Good for larger projects. For scripts and smaller work, IntelliJ IDEA with the Python plugin does the job.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formatting:&lt;/strong&gt; &lt;a class="link" href="https://black.readthedocs.io/" target="_blank" rel="noopener"
 &gt;Black&lt;/a&gt;: opinionated formatter, no configuration needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://docs.astral.sh/ruff/" target="_blank" rel="noopener"
 &gt;Ruff&lt;/a&gt;: extremely fast linter and formatter, replacing Flake8 + isort in most setups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency management:&lt;/strong&gt; &lt;a class="link" href="https://docs.astral.sh/uv/" target="_blank" rel="noopener"
 &gt;uv&lt;/a&gt;: modern, fast package manager replacing pip/virtualenv for most workflows.&lt;/p&gt;
&lt;h2 id="where-i-use-it"&gt;Where I use it
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Infrastructure automation and scripting alongside Ansible&lt;/li&gt;
&lt;li&gt;Data processing and log analysis&lt;/li&gt;
&lt;li&gt;CLI tooling for internal workflows&lt;/li&gt;
&lt;li&gt;Quick API clients and integration scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/3/" target="_blank" rel="noopener"
 &gt;docs.python.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://realpython.com/" target="_blank" rel="noopener"
 &gt;Real Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>