Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Goroutines and Channels: Go's Concurrency Model
A goroutine is a cheap unit of execution that starts with a 2 KB stack and that the runtime spreads over a few OS threads; a channel is a meeting point between two goroutines that does not behave like a queue. The cost of 100,000 goroutines, the G-M-P scheduler, asynchronous code without async/await, unbuffered and buffered channels, select and timeouts, a table of nil and closed channels, a fan-out/fan-in stock check in Bookstore, and goroutine leaks.
Go Generics and Iterators: Type Parameters, Constraints, range-over-func and Generic Methods
In Go a constraint is a type set: unless you write ~int64, a named type such as Money cannot be passed to a generic function that asks for int64. Pagination in Bookstore with a generic Page[T], cmp.Ordered and comparable, how Go differs from C# generics (no variance, GC shape stenciling), an iter.Seq iterator that groups books by author, the yield trap, a comparison with the LINQ mindset, and Go 1.27's generic methods.
Error Handling in Go: Error Values, Wrapping, errors.Is/As/AsType and panic
In Go an error is a return value: sentinel errors are recognised with errors.Is, custom error types with errors.As or Go 1.26's errors.AsType, and %w adds context while keeping the chain. ErrOutOfStock and ValidationError in Bookstore, collecting validation problems with errors.Join, the trap of wrapping a pointer error with %w and the Go 1.27 vet check that catches it, mapping errors to 404, a handler panic producing an empty reply, and a recover middleware.
Structs, Methods and Interfaces in Go: OOP Without Classes, Embedding and Implicit Interfaces
Go has no classes: data lives in structs and behaviour in methods; a method that changes state needs a pointer receiver, and interfaces are implicit and declared small on the side that uses them. Bookstore's order model (NewOrder, embedding Timestamps, MarkPaid), memstore and sqlstore behind orders.Repository, accept interfaces return structs, Stringer, type switches, the method set error and the nil interface trap caught by staticcheck.
Go Fundamentals: Types, Zero Values, Slices, Maps, Pointers and Control Flow
In Go a slice is a small header made of a pointer, len and cap, and sub-slices share the same backing array, which is why a filter working on books[:0] corrupts the original catalog. The zero value philosophy, constants with iota, strings vs bytes vs runes and the len trap with Turkish characters, append growing capacity, nil maps and random map order, pointers and Go 1.26's new(expr), the 1.22 loop variable and nil slices turning into null in JSON.
Installing Go, Modules and Project Layout: go.mod, Packages, internal/ and cmd/
A Go module is defined by go.mod: since Go 1.21 the go line is a binding minimum version, go.sum holds a hash for every dependency, and downloads are verified through proxy.golang.org and sum.golang.org. The story of the version go mod init writes, the toolchain line and GOTOOLCHAIN, staticcheck via the tool directive, exporting with uppercase names, the internal/ and cmd/ layout, go work, go mod tidy -diff and Go 1.27 merging require blocks into two.
What Is Go and Why Does It Exist? Go's Philosophy, Toolchain and When to Choose It, for C# Developers
Go is a small, natively compiled language that carries its runtime inside the binary, born at Google as an answer to slow builds and complexity in large codebases. A two-endpoint Bookstore service as a single 9.9 MB Windows .exe that starts in 10 ms and uses 12 MB, a comparison table with ASP.NET Core, go build/vet/fmt/fix/doc, cross-compiling, the six-month release policy and when to choose Go.