mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-30 20:49:49 +02:00
Add go roadmap content
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
# Anonymous Functions
|
||||
|
||||
Anonymous functions in Go are functions declared without a name, also known as function literals or lambda functions. They can be assigned to variables, passed as arguments to other functions, or executed immediately. Anonymous functions are useful for short-lived operations, callback implementations, goroutine creation, and situations where defining a named function would be overkill. They have access to variables in their enclosing scope, making them effective for creating closures. Common use cases include event handlers, sorting custom comparisons, and implementing functional programming patterns. Anonymous functions help keep code concise and localized when full function definitions aren't necessary.
|
||||
Functions declared without names, also called function literals or lambdas. Can be assigned to variables, passed as arguments, or executed immediately. Useful for short operations, callbacks, goroutines, and closures. Access enclosing scope variables. Common in event handlers and functional patterns.
|
@@ -1,3 +1,3 @@
|
||||
# Arrays
|
||||
|
||||
Arrays in Go are fixed-size sequences of elements of the same type. The size of an array is part of its type, meaning arrays of different sizes are considered different types. Arrays are declared with a specific length and all elements are initialized to the zero value of the element type. While arrays have their uses, slices are more commonly used in Go because of their flexibility. Arrays are value types, meaning they are copied when assigned or passed to functions. Understanding arrays is important for grasping Go's type system and the foundation for slices.
|
||||
Fixed-size sequences of same-type elements. Size is part of the type, so different sizes are different types. Declared with specific length, initialized to zero values. Value types (copied when assigned/passed). Slices are more commonly used due to flexibility. Foundation for understanding Go's type system.
|
@@ -1,3 +1,3 @@
|
||||
# break
|
||||
|
||||
The `break` statement in Go immediately exits the innermost loop (for) or switch statement. In nested loops, break only exits the immediate loop unless used with a label to break out of outer loops. Labels allow you to specify which loop to break from, providing more control in complex nested structures. Break is essential for early loop termination when certain conditions are met, implementing search algorithms, and controlling loop flow based on runtime conditions. Understanding break helps you write more efficient loops that don't continue processing unnecessarily once their purpose is fulfilled.
|
||||
Immediately exits innermost loop or switch statement. In nested loops, only exits immediate loop unless used with labels to break outer loops. Essential for early termination when conditions are met. Helps write efficient loops that don't continue unnecessarily.
|
@@ -1,3 +1,3 @@
|
||||
# Buffered vs Unbuffered
|
||||
|
||||
Channels in Go can be either buffered or unbuffered, which affects their synchronization behavior. Unbuffered channels (created with `make(chan Type)`) provide synchronous communication - the sender blocks until a receiver is ready, ensuring tight synchronization between goroutines. Buffered channels (created with `make(chan Type, capacity)`) allow asynchronous communication up to their capacity - senders only block when the buffer is full, and receivers only block when it's empty. Unbuffered channels are useful for coordination and ensuring operations happen in sequence, while buffered channels help with performance optimization and decoupling producer-consumer timing. Understanding this distinction is crucial for designing effective concurrent systems.
|
||||
Unbuffered channels provide synchronous communication - sender blocks until receiver ready. Buffered channels allow asynchronous communication up to capacity. Unbuffered for coordination/sequencing, buffered for performance/decoupling. Critical distinction for concurrent system design.
|
@@ -1,3 +1,3 @@
|
||||
# bufio
|
||||
|
||||
The `bufio` package provides buffered I/O operations that wrap around existing `io.Reader` and `io.Writer` interfaces to improve performance. Buffered I/O reduces the number of system calls by reading or writing data in larger chunks. The package includes `Scanner` for convenient line-by-line reading, `Reader` for buffered reading with methods like `ReadLine()` and `ReadString()`, and `Writer` for buffered writing. It's particularly useful for processing large files, network operations, and any scenario where frequent small I/O operations would be inefficient. Understanding buffered I/O is important for building efficient applications that handle substantial amounts of data.
|
||||
Provides buffered I/O operations wrapping io.Reader/Writer interfaces for better performance. Reduces system calls by reading/writing larger chunks. Includes Scanner for line reading, Reader for buffered reading, Writer for buffered writing. Essential for efficient large file/network operations.
|
@@ -1,3 +1,3 @@
|
||||
# Build Constraints & Tags
|
||||
|
||||
Build constraints (also known as build tags) are special comments that control which files are included when building Go programs. They allow you to create platform-specific code, environment-specific builds, or feature toggles. Build constraints are placed at the top of Go files and use the `//go:build` directive (or the older `// +build` format). Common use cases include building different versions for different operating systems, architectures, or creating debug vs production builds. Understanding build constraints is essential for creating portable Go applications that can adapt to different environments and requirements.
|
||||
Special comments controlling which files are included when building. Use `//go:build` directive for platform-specific code, environment builds, or feature toggles. Common for different OS/architectures or debug vs production builds. Essential for portable Go applications.
|
@@ -1,3 +1,3 @@
|
||||
# Building CLIs
|
||||
|
||||
Go is an excellent choice for building command-line interface (CLI) applications due to its fast compilation, single binary distribution, and rich ecosystem of CLI libraries. You can build CLIs using the standard `flag` package for simple cases, or leverage powerful frameworks like Cobra (used by kubectl, Hugo), urfave/cli, or Bubble Tea for interactive applications. Go CLIs benefit from cross-compilation support, allowing you to build binaries for different platforms easily. Building CLIs is a great way to learn Go while creating useful tools for automation, development workflows, and system administration.
|
||||
Go excels at CLI development due to fast compilation, single binary distribution, and rich ecosystem. Use standard `flag` package or frameworks like Cobra, urfave/cli, Bubble Tea. Cross-compilation support for multiple platforms. Great for learning Go while building useful tools.
|
@@ -1,3 +1,3 @@
|
||||
# Call by Value
|
||||
|
||||
Go uses call by value for function arguments, meaning that when you pass a variable to a function, Go creates a copy of the value rather than passing the original variable. This applies to all types including integers, strings, structs, and arrays. For large data structures, this copying can be expensive, which is why pointers, slices, and maps (which contain references) are often used instead. Call by value provides safety by preventing functions from accidentally modifying the caller's data, but it also means that functions cannot modify the original values unless you explicitly pass pointers. Understanding this behavior is crucial for effective Go programming and performance optimization.
|
||||
Go creates copies of values when passing to functions, not references to originals. Applies to all types including structs and arrays. Provides safety but can be expensive for large data. Use pointers, slices, maps for references. Critical for performance optimization.
|
@@ -1,3 +1,3 @@
|
||||
# Channels
|
||||
|
||||
Channels are Go's primary mechanism for communication between goroutines, following the principle "Don't communicate by sharing memory; share memory by communicating." Channels are typed conduits that allow you to send and receive values between goroutines safely. They can be created using the `make()` function and come in two varieties: buffered and unbuffered. Channels can be used to synchronize goroutine execution, pass data between concurrent processes, and coordinate complex concurrent operations. Understanding channels is essential for writing effective concurrent programs in Go.
|
||||
Primary mechanism for goroutine communication following "share memory by communicating" principle. Typed conduits created with `make()`. Come in buffered and unbuffered varieties. Used for synchronization, data passing, and coordinating concurrent operations. Essential for concurrent programming.
|
@@ -1,3 +1,3 @@
|
||||
# Closures
|
||||
|
||||
Closures in Go are functions that capture and access variables from their surrounding scope, even after the outer function returns. They're created when a function references variables declared outside its body, "closing over" those variables. Closures are useful for creating specialized functions, implementing callbacks, maintaining state between function calls, and building factories or configuration functions. Since the captured variables remain accessible to the closure, they can be modified across multiple calls. This makes closures powerful for event handling, iterator patterns, and functional programming techniques. Understanding closures is important for writing flexible, reusable code and working with higher-order functions.
|
||||
Functions capturing variables from surrounding scope, accessible even after outer function returns. "Close over" external variables for specialized functions, callbacks, state maintenance. Useful for event handling, iterators, functional programming. Important for flexible, reusable code.
|
@@ -1,3 +1,3 @@
|
||||
# Cobra
|
||||
|
||||
Cobra is a powerful library for creating modern CLI applications in Go. It's used by many popular projects including Kubernetes (kubectl), Hugo, and GitHub CLI. Cobra provides features like nested subcommands, global and local flags, intelligent suggestions, automatic help generation, and shell completion. It follows POSIX standards and offers a clean API for building complex command-line interfaces. Cobra also includes a command generator to bootstrap CLI applications quickly. The library handles argument parsing, flag management, and help text generation automatically, allowing developers to focus on implementing command logic rather than CLI infrastructure.
|
||||
Powerful library for modern CLI applications. Used by kubectl, Hugo, GitHub CLI. Provides nested subcommands, flags, intelligent suggestions, auto help generation, shell completion. Follows POSIX standards with clean API. Includes command generator for quick bootstrapping.
|
@@ -1,3 +1,3 @@
|
||||
# Concurrency Patterns
|
||||
|
||||
Concurrency patterns in Go are established design approaches for structuring concurrent programs using goroutines and channels. These patterns provide proven solutions for common concurrent programming challenges such as distributing work, aggregating results, and coordinating multiple processes. Key patterns include fan-in (merging multiple inputs), fan-out (distributing work to multiple workers), pipelines (chaining operations), worker pools (managing a fixed number of workers), and pub-sub (publisher-subscriber communication). Understanding these patterns helps you build efficient, scalable concurrent applications while avoiding common pitfalls like race conditions and deadlocks.
|
||||
Established design approaches for structuring concurrent programs using goroutines and channels. Key patterns: fan-in (merging inputs), fan-out (distributing work), pipelines (chaining operations), worker pools, pub-sub communication. Help build efficient, scalable apps while avoiding race conditions and deadlocks.
|
@@ -1,3 +1,3 @@
|
||||
# Conditionals
|
||||
|
||||
Conditionals in Go allow your program to make decisions and execute different code paths based on certain conditions. Go provides `if` statements for basic conditional logic, `if-else` for binary decisions, and `switch` statements for multiple condition checking. The `if` statement can include an optional initialization statement, and conditions don't require parentheses but the body must be enclosed in braces. Go's `switch` statement is more powerful than in many languages, supporting expression switches, type switches, and fallthrough behavior. Conditionals are fundamental for controlling program flow and implementing business logic.
|
||||
Control program flow based on conditions. `if` for basic logic, `if-else` for binary decisions, `switch` for multiple conditions. `if` supports optional initialization, no parentheses needed but braces required. `switch` supports expressions, type switches, fallthrough. Fundamental for business logic.
|
@@ -1,3 +1,3 @@
|
||||
# `context` Package
|
||||
|
||||
The `context` package provides a way to carry deadlines, cancellation signals, and request-scoped values across API boundaries and between processes. Context is essential for building robust concurrent applications, especially web services and APIs. It allows you to cancel long-running operations, set timeouts, and pass request-specific data through your application. The context is typically the first parameter of functions and is passed down through the call stack. Understanding context is crucial for writing production-ready Go applications that can handle cancellation, timeouts, and cleanup gracefully.
|
||||
Carries deadlines, cancellation signals, and request-scoped values across API boundaries. Essential for robust concurrent applications, especially web services. Enables cancelling long-running operations, setting timeouts, passing request data. Typically first parameter passed down call stack.
|
@@ -1,3 +1,3 @@
|
||||
# continue
|
||||
|
||||
The `continue` statement in Go skips the rest of the current iteration and jumps to the next iteration of the loop. It only affects the innermost loop unless used with labels to specify which loop to continue. Continue is useful for skipping processing of certain elements that don't meet specific criteria, implementing filtering logic within loops, and avoiding deeply nested conditional structures. It helps make loops more readable by handling special cases early and allowing the main logic to flow naturally. Understanding continue enables you to write cleaner, more efficient loops that focus on the elements that actually need processing.
|
||||
Skips rest of current iteration and jumps to next loop iteration. Only affects innermost loop unless used with labels. Useful for filtering elements, handling special cases early, avoiding nested conditionals. Makes loops cleaner and more efficient.
|
@@ -1,3 +1,3 @@
|
||||
# Data Types
|
||||
|
||||
Go has a rich set of built-in data types that form the foundation of all Go programs. These include basic types like integers (int8, int16, int32, int64), unsigned integers (uint8, uint16, uint32, uint64), floating-point numbers (float32, float64), complex numbers (complex64, complex128), booleans, strings, and runes (Unicode characters). Go is statically typed, meaning variable types are determined at compile time, which helps catch errors early and improves performance. Understanding Go's type system is crucial for writing efficient and reliable programs, as it affects memory usage, performance, and how you structure your data.
|
||||
Rich set of built-in types: integers (int8-64), unsigned integers (uint8-64), floats (float32/64), complex numbers, booleans, strings, runes. Statically typed - types determined at compile time for early error detection and performance. Crucial for efficient, reliable programs.
|
@@ -1,3 +1,3 @@
|
||||
# echo
|
||||
|
||||
Echo is a high-performance, minimalist web framework for Go that focuses on ease of use and speed. It provides essential features for building APIs and web applications including optimized routing, middleware support, data binding, validation, and rendering. Echo's API is designed to be intuitive and requires minimal learning curve while offering powerful features like automatic TLS support, HTTP/2 support, and WebSocket handling. The framework includes built-in middleware for CORS, JWT authentication, logging, and compression. Echo is particularly popular for building RESTful APIs and microservices due to its excellent performance characteristics and comprehensive feature set.
|
||||
High-performance, minimalist web framework focusing on ease and speed. Provides routing, middleware, data binding, validation, rendering. Features automatic TLS, HTTP/2, WebSocket support. Built-in middleware for CORS, JWT, logging, compression. Popular for RESTful APIs and microservices.
|
@@ -1,3 +1,3 @@
|
||||
# Embedding Interfaces
|
||||
|
||||
Interface embedding in Go allows you to create new interfaces by combining existing ones, promoting interface composition and reusability. When you embed an interface in another interface, the new interface automatically includes all methods from the embedded interface. This creates interface hierarchies and enables building complex interfaces from simpler, focused ones. Interface embedding supports the principle of composition over inheritance, allows for incremental interface definition, and helps create more maintainable and flexible designs. It's commonly used in standard library interfaces and is essential for building modular, extensible systems where interfaces can grow organically while maintaining backward compatibility.
|
||||
Create new interfaces by combining existing ones, promoting composition and reusability. Embedded interface methods automatically included. Enables interface hierarchies from simpler, focused interfaces. Supports composition over inheritance for modular, extensible systems.
|
@@ -1,3 +1,3 @@
|
||||
# Empty Interfaces
|
||||
# Empty Interface
|
||||
|
||||
Empty interfaces (`interface{}`) in Go can hold values of any type since they specify no methods. While powerful for creating flexible APIs and generic containers, they sacrifice compile-time type safety for runtime flexibility. With Go 1.18+, generics often provide a better alternative to empty interfaces for type-safe generic programming. Empty interfaces are still useful for scenarios like JSON unmarshaling, building general-purpose containers, implementing reflection-based libraries, and interfacing with dynamic systems. When using empty interfaces, you typically need type assertions or type switches to work with the actual values, so they should be used judiciously and with proper error handling.
|
||||
The empty interface `interface{}` can hold values of any type since every type implements at least zero methods. Used for generic programming before Go 1.18 generics. Requires type assertions or type switches to access underlying values. Common in APIs handling unknown data types.
|
@@ -1,3 +1,3 @@
|
||||
# Error Handling Basics
|
||||
|
||||
Error handling in Go follows an explicit approach where functions return an error as their last return value. Unlike languages that use exceptions, Go treats errors as values that must be explicitly checked and handled. The conventional pattern is to check if an error is nil (no error occurred) or handle the error appropriately. This approach makes error handling visible in the code flow and encourages developers to think about and handle potential failures at each step. Go's error handling philosophy emphasizes clarity and forces you to consider what should happen when things go wrong.
|
||||
Go uses explicit error handling with error return values. Functions return error as last value. Check `if err != nil` pattern. Create errors with `errors.New()` or `fmt.Errorf()`. No exceptions - errors are values to be handled explicitly.
|
@@ -1,3 +1,3 @@
|
||||
# fan-in
|
||||
# Fan-in
|
||||
|
||||
Fan-in is a concurrency pattern where multiple input channels are merged into a single output channel. This pattern is useful for aggregating results from multiple goroutines, combining data streams, or centralizing processing from various sources. Implementation typically involves a function that starts goroutines to read from each input channel and forward values to a shared output channel. Fan-in helps simplify complex systems by providing a single point to collect distributed work results. It's commonly used in scenarios like distributed processing, load balancing, and event aggregation where you need to merge multiple concurrent data streams into one.
|
||||
Concurrency pattern merging multiple input channels into single output channel. Allows collecting results from multiple goroutines. Typically implemented with select statement or separate goroutines for each input. Useful for aggregating parallel processing results.
|
@@ -1,3 +1,3 @@
|
||||
# fan-out
|
||||
# Fan-out
|
||||
|
||||
Fan-out is a concurrency pattern where work from a single input channel is distributed to multiple worker goroutines for parallel processing. This pattern is effective for distributing computationally intensive tasks across multiple processors or handling high-throughput scenarios. Implementation involves multiple goroutines reading from the same input channel, with Go's runtime automatically distributing the work among available workers. Fan-out improves performance by leveraging parallelism and is particularly useful for CPU-bound tasks, batch processing, and scenarios where work can be processed independently. It's often combined with fan-in to collect results after parallel processing.
|
||||
Concurrency pattern distributing work from single source to multiple workers. Typically uses one input channel feeding multiple goroutines. Each worker processes items independently. Useful for parallelizing CPU-intensive tasks and increasing throughput through parallel processing.
|
@@ -1,3 +1,3 @@
|
||||
# flag
|
||||
|
||||
The `flag` package provides command-line flag parsing functionality for Go programs. It supports various flag types including strings, integers, booleans, and durations, with automatic help generation and error handling. Flags can be defined using functions like `flag.String()`, `flag.Int()`, and `flag.Bool()`, and are parsed with `flag.Parse()`. The package handles both short and long flag formats, provides default values, and generates usage information automatically. While suitable for simple CLI applications, more complex command-line interfaces often benefit from libraries like Cobra or urfave/cli. Understanding the flag package is essential for creating basic command-line tools and scripts.
|
||||
Standard library package for parsing command-line flags. Supports string, int, bool, duration flags with default values and descriptions. Automatically generates help text. Simple API for basic CLI argument parsing before using frameworks like Cobra.
|
@@ -1,3 +1,3 @@
|
||||
# for loop
|
||||
|
||||
The for loop is Go's only looping construct, but it's flexible enough to handle all iteration scenarios. The traditional three-component form `for init; condition; post` works like loops in other languages, while you can omit components for different behaviors. For example, omitting init and post creates a while-style loop, and omitting all components creates an infinite loop. The for loop is essential for repetitive operations, iterating over data structures, and implementing algorithms that require repeated execution. Its simplicity and versatility make it a fundamental tool for controlling program flow and processing collections of data.
|
||||
Go's only looping construct, incredibly flexible for all iteration needs. Classic form: initialization, condition, post statements. Omit components for different behaviors (infinite, while-like). Use with `break`, `continue`, labels for nested loops. `for range` for convenient collection iteration.
|
@@ -1,3 +1,3 @@
|
||||
# for range
|
||||
# for-range
|
||||
|
||||
The `for range` loop in Go provides a convenient way to iterate over arrays, slices, maps, strings, and channels. It automatically handles iteration logic and provides access to both index/key and value for each element. When ranging over slices or arrays, you get index and value; over maps, you get key and value; over strings, you get byte index and rune value; and over channels, you get the received values. You can use the blank identifier `_` to ignore index/key if you only need values. The range loop is essential for processing collections and is more idiomatic and safer than manual index-based iteration in most cases.
|
||||
Special form of for loop for iterating over arrays, slices, maps, strings, and channels. Returns index/key and value. For strings, returns rune index and rune value. For channels, returns only values. Use blank identifier `_` to ignore unwanted return values.
|
@@ -1,3 +1,3 @@
|
||||
# Functions Basics
|
||||
# Function Basics
|
||||
|
||||
Function basics in Go cover the fundamental syntax and concepts for creating reusable code blocks. Functions are declared with the `func` keyword, followed by name, parameters in parentheses, optional return types, and the function body in braces. Go functions can have zero or more parameters, each with a specified type, and can return zero or more values. Function names that start with capital letters are exported (public), while lowercase names are unexported (private) to the package. Understanding function basics is essential for organizing code, creating modular programs, and following Go's conventions for code structure and visibility.
|
||||
Reusable code blocks declared with `func` keyword. Support parameters, return values, multiple returns. First-class citizens - can be assigned to variables, passed as arguments. Fundamental building blocks for organizing code logic.
|
@@ -1,3 +1,3 @@
|
||||
# Functions
|
||||
|
||||
Functions are the fundamental building blocks of Go programs that allow you to organize code into reusable pieces. In Go, functions are declared using the `func` keyword followed by the function name, parameters, return types, and function body. Functions can accept zero or more parameters, return zero or more values, and can be called from other parts of your program. Go functions have several unique features including multiple return values, named return values, variadic parameters, and first-class function support. Understanding functions is crucial for writing clean, maintainable, and efficient Go code.
|
||||
First-class citizens in Go. Declared with `func` keyword, support parameters and return values. Can be assigned to variables, passed as arguments, returned from other functions. Support multiple return values, named returns, and variadic parameters. Building blocks of modular code.
|
@@ -1,3 +1,3 @@
|
||||
# Generics
|
||||
|
||||
Generics, introduced in Go 1.18, allow you to write functions and types that can work with different data types while maintaining type safety. They enable you to create reusable code that doesn't sacrifice performance or type checking. With generics, you can write a single function or data structure that works with multiple types instead of having to duplicate code for each type. Generics use type parameters (written in square brackets) and type constraints to define which types are acceptable. This feature makes Go code more flexible and reduces code duplication while preserving the language's strong typing system.
|
||||
Introduced in Go 1.18, allow functions and types to work with different data types while maintaining type safety. Enable reusable code without sacrificing performance. Use type parameters (square brackets) and constraints. Reduce code duplication while preserving strong typing.
|
@@ -1,3 +1,3 @@
|
||||
# gin
|
||||
|
||||
Gin is a popular HTTP web framework for Go that emphasizes performance and developer productivity. It provides a lightweight yet feature-rich foundation for building APIs and web services with minimal boilerplate code. Gin offers fast routing, middleware support, JSON validation, error management, and built-in rendering for JSON, XML, and HTML. Its API is clean and intuitive, making it easy to build RESTful services quickly. Gin includes useful features like parameter binding, file uploads, static file serving, and logging middleware. It's an excellent choice for developers who want more features than the standard library while maintaining high performance and simplicity.
|
||||
Popular HTTP web framework emphasizing performance and productivity. Lightweight foundation for APIs/web services with minimal boilerplate. Fast routing, middleware, JSON validation, error management, built-in rendering. Clean API for RESTful services. Includes parameter binding, uploads, static files.
|
@@ -1,3 +1,3 @@
|
||||
# go build
|
||||
|
||||
The `go build` command compiles Go packages and creates executable binaries. It reads Go source files, resolves dependencies, and produces optimized machine code for the target platform. The command can build single files, packages, or entire modules. By default, it creates an executable with the package name in the current directory. You can specify output names with `-o flag`, target different platforms with `GOOS` and `GOARCH` environment variables, and control various compilation options. Understanding `go build` is essential for creating deployable applications and optimizing build processes for different environments.
|
||||
Compiles Go packages and dependencies into executable binaries. Supports cross-compilation for different OS/architectures via GOOS/GOARCH. Includes build constraints, custom flags, optimization levels. Produces statically linked binaries by default. Essential for deployment and distribution.
|
@@ -1,3 +1,3 @@
|
||||
# go fmt
|
||||
|
||||
The `go fmt` command automatically formats Go source code according to Go's official style guidelines. It standardizes indentation, spacing, alignment, and other formatting aspects to ensure consistent code style across all Go projects. The tool is opinionated and non-configurable, which eliminates debates about code formatting and ensures uniformity in the Go ecosystem. Most editors can be configured to run `go fmt` automatically on save. Using `go fmt` regularly keeps your code clean, readable, and consistent with Go community standards, making collaboration easier and code reviews more focused on logic rather than style.
|
||||
Automatically formats Go source code according to official style guidelines. Standardizes indentation, spacing, alignment for consistent code style. Opinionated and non-configurable, eliminating formatting debates. Essential for clean, readable, community-standard code.
|
@@ -1,3 +1,3 @@
|
||||
# go mod
|
||||
|
||||
The `go mod` command is the primary tool for managing Go modules and dependencies. It provides subcommands for initializing modules (`init`), adding dependencies (`get`), removing unused dependencies (`tidy`), creating vendor directories (`vendor`), and verifying dependencies (`verify`). The command works with `go.mod` and `go.sum` files to track module requirements and ensure reproducible builds. Understanding `go mod` is essential for modern Go development, as it handles dependency management, version resolution, and module publishing. It replaced the older GOPATH-based workflow and is fundamental for building maintainable Go projects.
|
||||
Command-line tool for module management. `go mod init` creates module, `go mod tidy` cleans dependencies, `go mod download` fetches modules. Manages go.mod and go.sum files. Essential commands for dependency management and version control.
|
@@ -1,3 +1,3 @@
|
||||
# go run
|
||||
|
||||
The `go run` command compiles and executes Go programs in a single step without creating a persistent binary file. It's perfect for development, testing small programs, and running scripts. When you use `go run main.go`, Go compiles the code to a temporary executable and runs it immediately, then cleans up the temporary files. This command is ideal for quick iterations during development, running one-off scripts, or testing code changes without the overhead of separate build steps. It accepts the same flags as `go build` and can run multiple files or entire packages.
|
||||
Compiles and executes Go programs in one step without creating executable files. Useful for testing, development, and running scripts. Takes Go source files as arguments. Convenient for quick execution during development without build artifacts.
|
@@ -1,3 +1,3 @@
|
||||
# go test
|
||||
|
||||
The `go test` command is Go's built-in tool for running tests, benchmarks, and examples. It automatically discovers test files (ending with `_test.go`), compiles them with the package code, and executes test functions. The command supports various flags for controlling test behavior, including `-v` for verbose output, `-run` for running specific tests, `-bench` for benchmarks, and `-cover` for coverage analysis. It can run tests in parallel, generate test coverage reports, and integrate with continuous integration systems. Mastering `go test` is crucial for maintaining code quality and implementing test-driven development practices.
|
||||
Command for running tests in Go packages. Automatically finds and executes functions starting with `Test`. Supports benchmarks (`Benchmark`), examples (`Example`), and sub-tests. Includes coverage analysis, parallel execution, and various output formats. Essential for TDD and quality assurance.
|
@@ -1,3 +1,3 @@
|
||||
# GORM
|
||||
|
||||
GORM is a feature-rich Object-Relational Mapping (ORM) library for Go that simplifies database interactions. It provides an intuitive API for database operations, automatic migrations, associations (belongs to, has one, has many, many to many), hooks (before/after create/save/update/delete), transactions, and connection pooling. GORM supports multiple databases including PostgreSQL, MySQL, SQLite, and SQL Server. It includes advanced features like soft deletes, composite primary keys, database resolver for read/write splitting, and plugin system for extensibility. While ORMs add abstraction overhead, GORM is excellent for rapid development and complex data relationships.
|
||||
Popular Object-Relational Mapping library for Go. Provides database abstraction with struct-based models, automatic migrations, associations, and query building. Supports multiple databases (MySQL, PostgreSQL, SQLite, SQL Server). Features hooks, transactions, and connection pooling.
|
@@ -1,3 +1,3 @@
|
||||
# Goroutines
|
||||
|
||||
Goroutines are lightweight threads managed by the Go runtime that enable concurrent execution of functions. They are one of Go's most powerful features, allowing you to run thousands or even millions of concurrent operations with minimal memory overhead. Goroutines are created simply by prefixing a function call with the `go` keyword. The Go runtime automatically handles scheduling goroutines across available CPU cores, making concurrent programming much easier than traditional threading models. Goroutines communicate through channels and are fundamental to Go's approach to concurrency and parallelism.
|
||||
Lightweight threads managed by Go runtime enabling concurrent function execution. Created with `go` keyword prefix. Minimal memory overhead, can run thousands/millions concurrently. Runtime handles scheduling across CPU cores. Communicate through channels, fundamental to Go's concurrency.
|
@@ -1,3 +1,3 @@
|
||||
# goto (discouraged)
|
||||
|
||||
The `goto` statement in Go allows jumping to labeled statements within the same function, but its use is strongly discouraged in modern Go programming. While goto exists for specific use cases like breaking out of nested loops or handling complex cleanup scenarios, it generally makes code harder to read, maintain, and debug. Go provides better alternatives like labeled break/continue statements, proper function decomposition, and structured control flow. Most situations where goto might seem necessary can be solved more elegantly with Go's other control structures. Understanding why goto is discouraged helps you write cleaner, more maintainable code that follows Go's philosophy of simplicity and clarity.
|
||||
Go includes `goto` statement but discourages its use. Can only jump to labels within same function. Creates unstructured code flow making programs hard to read, debug, and maintain. Use structured control flow (loops, functions, conditionals) instead. Rarely needed in modern Go programming.
|
@@ -1,3 +1,3 @@
|
||||
# if-else
|
||||
|
||||
The if-else statement in Go extends the basic if statement by providing an alternative code path when the condition is false. You can chain multiple conditions using else if to handle complex decision logic. Go's if-else maintains the same syntax rules as if statements - no parentheses required around conditions, but braces are mandatory around bodies. The else clause must be on the same line as the closing brace of the if block. If-else statements are essential for binary decisions, error handling patterns, and implementing branching logic where you need to choose between different execution paths based on conditions.
|
||||
Basic conditional statements for binary decision making. `if` tests condition, `else` handles alternative path. Can include optional initialization statement. No parentheses needed around condition but braces required. Foundation of program control flow.
|
@@ -1,3 +1,3 @@
|
||||
# if
|
||||
|
||||
The if statement in Go provides conditional execution of code blocks based on boolean expressions. Go's if statements don't require parentheses around conditions but must have braces around the body, even for single statements. A unique feature is the ability to include an initialization statement before the condition, which is useful for declaring variables with limited scope. If statements can be chained with else if and else clauses to handle multiple conditions. They're fundamental for controlling program flow, implementing business logic, and making decisions based on runtime conditions. Understanding if statements is essential for any Go program with conditional behavior.
|
||||
Basic conditional statement for executing code based on boolean conditions. Supports optional initialization statement before condition check. No parentheses required around condition but braces mandatory. Can be chained with else if for multiple conditions. Foundation of control flow.
|
@@ -1,3 +1,3 @@
|
||||
# Interfaces
|
||||
|
||||
Interfaces in Go define a contract by specifying a set of method signatures that a type must implement. Unlike many other languages, Go interfaces are implemented implicitly - a type implements an interface simply by implementing all the methods declared in the interface. This approach promotes loose coupling and makes code more flexible and testable. Interfaces are central to Go's type system and enable polymorphism, allowing different types to be used interchangeably as long as they satisfy the same interface. They are essential for writing modular, extensible Go programs.
|
||||
Define contracts specifying method signatures without implementation. Types satisfy interfaces implicitly by implementing required methods. Enable polymorphism and loose coupling. Empty interface `interface{}` accepts any type. Foundation of Go's type system and composition patterns.
|
@@ -1,3 +1,3 @@
|
||||
# Introduction to Go
|
||||
|
||||
Go (also known as Golang) is a statically typed, compiled programming language developed by Google in 2007 and released in 2009. Created by Robert Griesemer, Rob Pike, and Ken Thompson, Go was designed to address the challenges of large-scale software development at Google. It combines the efficiency and safety of statically typed languages with the ease of programming of dynamically typed languages. Go emphasizes simplicity, readability, and efficiency, making it ideal for building scalable web services, cloud applications, and system tools. Its key features include fast compilation, garbage collection, built-in concurrency support, and a comprehensive standard library.
|
||||
Statically typed, compiled programming language developed at Google. Designed for simplicity, concurrency, and performance. Features garbage collection, strong typing, efficient compilation, built-in concurrency with goroutines and channels. Excellent for backend services, CLI tools, and distributed systems.
|
@@ -1,3 +1,3 @@
|
||||
# Iterating Maps
|
||||
|
||||
Iterating over maps in Go is done using the `for range` loop, which provides access to both keys and values. The iteration order is not guaranteed and can vary between runs, making maps unsuitable when order matters. You can iterate over keys only, values only, or both depending on your needs. Common patterns include checking if keys exist, building new collections from map data, and processing key-value pairs. When you need ordered iteration, you typically collect keys in a slice, sort them, and then iterate through the sorted keys to access map values in order.
|
||||
Use `for range` to iterate over maps, returns key and value pairs. Iteration order is random for security reasons. Use blank identifier `_` to ignore key or value. Cannot modify map during iteration unless creating new map. Safe to delete during iteration.
|
@@ -1,3 +1,3 @@
|
||||
# Iterating Strings
|
||||
|
||||
Iterating over strings in Go using `for range` automatically handles UTF-8 decoding and provides Unicode code points (runes) rather than individual bytes. This is important for properly handling international characters and emojis. The loop gives you the byte index and the rune value at each position. If you need to work with individual bytes instead of runes, you can convert the string to a byte slice first. Understanding string iteration is crucial for text processing, validation, and building applications that work correctly with international text and various character encodings.
|
||||
Iterate over strings with `for range` to get runes (Unicode code points) not bytes. Returns index and rune value. Direct indexing `str[i]` gives bytes. Use `[]rune(str)` to convert to rune slice for random access. Important for Unicode handling.
|
@@ -1,3 +1,3 @@
|
||||
# encoding/json
|
||||
|
||||
The `encoding/json` package provides functionality for encoding and decoding JSON data, which is essential for modern web APIs and data interchange. It can marshal Go values to JSON and unmarshal JSON to Go values automatically using reflection. The package supports struct tags for field customization, custom marshaling/unmarshaling through interfaces, and handles various data types including maps, slices, and nested structures. Understanding JSON encoding is crucial for building web services, consuming APIs, and working with configuration files. The package is optimized for performance and provides flexible options for handling different JSON formats and requirements.
|
||||
Provides JSON encoding/decoding functionality essential for web APIs and data interchange. Marshals Go values to JSON and unmarshals JSON to Go using reflection. Supports struct tags, custom marshaling, various data types. Crucial for web services and API consumption.
|
@@ -1,3 +1,3 @@
|
||||
# Logging
|
||||
|
||||
Logging is essential for monitoring, debugging, and maintaining Go applications in production. Go's standard library includes a basic `log` package, and Go 1.21 introduced the structured `slog` package for more advanced logging needs. Popular third-party logging libraries include Zap (high-performance), Zerolog (zero-allocation), and Logrus (feature-rich). Effective logging involves choosing appropriate log levels (debug, info, warn, error), structuring log messages for easy parsing, and configuring outputs for different environments. Good logging practices help with troubleshooting issues, monitoring application behavior, and maintaining system health.
|
||||
Essential for monitoring, debugging, maintaining production applications. Standard `log` package and `slog` (Go 1.21+) for structured logging. Popular libraries: Zap (high-performance), Zerolog (zero-allocation), Logrus (feature-rich). Use appropriate log levels and structured messages.
|
@@ -1,3 +1,3 @@
|
||||
# Loops
|
||||
|
||||
Go has only one looping construct: the `for` loop, but it's flexible enough to handle all looping scenarios. The basic `for` loop has three components: initialization, condition, and post statement. Go also supports `for range` loops for iterating over arrays, slices, maps, strings, and channels. You can create infinite loops by omitting conditions, and while-style loops by omitting initialization and post statements. Loop control statements like `break` and `continue` provide additional flow control. The simplicity of having just one loop construct makes Go code more consistent and easier to read.
|
||||
Go has only one looping construct: the flexible `for` loop. Basic form has initialization, condition, post statement. Supports `for range` for arrays, slices, maps, strings, channels. Can create infinite loops or while-style loops. Control with `break` and `continue`.
|
@@ -1,3 +1,3 @@
|
||||
# Maps
|
||||
|
||||
Maps in Go are built-in data structures that store key-value pairs, similar to hash tables or dictionaries in other languages. They provide fast lookups, insertions, and deletions based on unique keys. Maps are reference types and must be initialized before use, either with `make(map[KeyType]ValueType)` or with map literals. Keys must be comparable types (strings, numbers, booleans, arrays, structs with comparable fields), while values can be any type. Maps are essential for many programming tasks including caching, counting, grouping data, and implementing lookup tables.
|
||||
Built-in associative data type mapping keys to values. Reference types created with `make(map[KeyType]ValueType)` or map literals. Keys must be comparable types. Support insertion, deletion, lookup operations. Check existence with comma ok idiom: `value, ok := map[key]`.
|
@@ -1,3 +1,3 @@
|
||||
# Methods vs Functions
|
||||
|
||||
In Go, functions are standalone code blocks that can be called independently, while methods are functions associated with a specific type (called a receiver). Methods are defined by adding a receiver parameter between the `func` keyword and the method name. This allows you to call the method on instances of that type using dot notation. Methods enable object-oriented programming patterns in Go, allowing types to have behavior associated with them. Understanding the distinction between methods and functions is crucial for designing clean, maintainable Go code that follows idiomatic patterns.
|
||||
Methods are functions with receiver arguments, defined outside type declaration. Enable object-like behavior on types. Functions are standalone, methods belong to specific types. Methods can have value or pointer receivers. Both can accept parameters and return values.
|
@@ -1,3 +1,3 @@
|
||||
# Modules & Dependencies
|
||||
|
||||
Go modules are the standard way to manage dependencies in Go projects. A module is a collection of related Go packages stored together with go.mod and go.sum files that track dependencies and their versions. Modules enable reproducible builds, version management, and dependency resolution. The `go.mod` file defines the module path and lists dependencies, while `go.sum` contains checksums for security. Modules replaced the older GOPATH-based approach and are essential for building reliable, maintainable Go applications that depend on external libraries and packages.
|
||||
Go modules are the dependency management system introduced in Go 1.11. Define module with `go.mod` file containing module path and dependencies. Use `go get` to add dependencies, `go mod tidy` to clean up. Supports semantic versioning and replacement directives. Essential for modern Go development.
|
@@ -1,3 +1,3 @@
|
||||
# Multiple Return Values
|
||||
|
||||
Go functions can return multiple values, which is commonly used for returning both a result and an error. This pattern eliminates the need for exceptions and makes error handling explicit and visible in the code flow. Functions can return any number of values of different types, and callers can capture all values or ignore some using the blank identifier `_`. Multiple return values are essential for Go's error handling idiom, make functions more expressive, and reduce the need for complex data structures just to return multiple pieces of information. This feature contributes to Go's clean, readable code style and explicit error handling philosophy.
|
||||
Go functions can return multiple values, commonly used for returning result and error. Syntax: `func name() (Type1, Type2)`. Caller receives all returned values or uses blank identifier `_` to ignore unwanted values. Idiomatic for error handling pattern.
|
@@ -1,3 +1,3 @@
|
||||
# Mutexes
|
||||
|
||||
Mutexes (mutual exclusion locks) in Go's sync package provide a way to protect shared resources from concurrent access, preventing race conditions. A mutex ensures that only one goroutine can access a protected section of code at a time. Go provides `sync.Mutex` for exclusive access and `sync.RWMutex` for scenarios where you want to allow multiple concurrent readers but exclusive writers. Mutexes should be used sparingly in Go, as channels are often a better choice for communication between goroutines. However, mutexes are essential for protecting shared state that doesn't fit the channel communication model, such as caches, counters, or complex data structures.
|
||||
Mutual exclusion locks from sync package ensuring only one goroutine accesses shared resource at a time. Use `Lock()` before and `Unlock()` after critical section. RWMutex allows multiple readers or single writer. Essential for protecting shared data from race conditions.
|
@@ -1,3 +1,3 @@
|
||||
# Named Return Values
|
||||
|
||||
Named return values in Go allow you to specify names for return parameters in the function signature, creating variables that are automatically initialized to zero values and returned when the function ends. Using named returns can make code more readable by documenting what each return value represents, simplify complex functions with multiple return statements, and enable "naked" returns (just `return` without specifying values). However, they should be used judiciously as they can sometimes reduce clarity, especially in short functions. Named returns are most beneficial in longer functions where the return values' purpose might not be immediately clear from context.
|
||||
Function return parameters can be named and treated as variables within function. Initialized to zero values. `return` statement without arguments returns current values of named parameters. Improves readability and enables easier refactoring but use judiciously.
|
@@ -1,3 +1,3 @@
|
||||
# net/http (standard)
|
||||
# net/http Standard
|
||||
|
||||
The `net/http` package is Go's powerful standard library for building HTTP clients and servers without external dependencies. It provides everything needed to create web servers, make HTTP requests, handle routing, process form data, manage cookies, and implement middleware. The package includes types like `http.Server`, `http.Client`, `http.Request`, and `http.Response` for comprehensive HTTP functionality. You can build production-ready web applications using only the standard library, though many developers choose frameworks for additional convenience. Understanding `net/http` is fundamental for Go web development and provides the foundation that most Go web frameworks build upon.
|
||||
Standard library package for HTTP client/server functionality. Provides HTTP server with routing, middleware support, client for making requests. Handles TLS, HTTP/2, cookies, multipart forms. Foundation for web development without external frameworks.
|
@@ -1,3 +1,3 @@
|
||||
# ORMs & DB Access
|
||||
|
||||
Go provides several approaches for database access, ranging from low-level database drivers to full-featured Object-Relational Mapping (ORM) libraries. The standard `database/sql` package offers a consistent interface for working with SQL databases, while libraries like GORM provide higher-level ORM functionality and pgx offers PostgreSQL-specific optimizations. ORMs can simplify database operations by mapping database records to Go structs, handling relationships, and providing query builders. However, they may introduce overhead, so choosing between raw SQL, lightweight query builders, or full ORMs depends on your application's complexity and performance requirements.
|
||||
Go offers multiple database access approaches: raw SQL with database/sql, ORMs like GORM/Ent, and query builders. Choose based on complexity needs - raw SQL for performance, ORMs for rapid development, query builders for balance. Consider connection pooling and migrations.
|
@@ -1,3 +1,3 @@
|
||||
# os
|
||||
|
||||
The `os` package provides a platform-independent interface to operating system functionality including file operations, environment variables, process management, and system information. It includes functions for creating, reading, writing, and deleting files and directories, working with file permissions, and executing system commands. The package also provides access to command-line arguments, environment variables, and process signals. Understanding the `os` package is fundamental for building system tools, CLI applications, and any program that needs to interact with the file system or operating system services. It's essential for creating portable applications that work across different operating systems.
|
||||
Standard library package providing operating system interface. Handles file operations, environment variables, process management, and system information. Includes functions for file I/O, directory operations, process control, and cross-platform OS interactions. Essential for system programming.
|
@@ -1,3 +1,3 @@
|
||||
# Packages
|
||||
|
||||
Packages are Go's way of organizing and reusing code. Every Go program is made up of packages, with the main package being the entry point for executable programs. Packages group related functionality together and provide a namespace for code organization. Each package has a unique import path that identifies it, and you can import other packages to use their exported functions, types, and variables. Package names should be short, clear, and lowercase. Understanding packages is essential for structuring larger Go applications, creating reusable libraries, and collaborating with other developers through shared code.
|
||||
Fundamental unit of code organization in Go. Group related functions, types, and variables. Defined by package declaration at file top. Exported names start with capital letters. Import with `import` statement. Enable modularity, reusability, and namespace management.
|
@@ -1,3 +1,3 @@
|
||||
# pipeline
|
||||
# Pipeline
|
||||
|
||||
The pipeline pattern in Go connects multiple stages of processing where each stage runs concurrently and communicates through channels. Data flows from one stage to the next, with each stage performing a specific transformation or operation. Pipelines enable efficient streaming processing, memory efficiency (since you don't need to store all data at once), and natural parallelism. Each stage can run at its own pace, with channels providing buffering between stages. This pattern is excellent for data processing workflows, stream processing, and any scenario where you can break down complex operations into sequential, composable steps. Pipelines promote clean, modular code that's easy to test and reason about.
|
||||
Concurrency pattern chaining processing stages where output of one stage becomes input of next. Each stage runs concurrently using goroutines and channels. Enables parallel processing and separation of concerns. Common in data processing, transformation workflows, and streaming applications.
|
@@ -1,3 +1,3 @@
|
||||
# Pointers Basics
|
||||
# Pointer Basics
|
||||
|
||||
Pointer basics in Go involve understanding how to declare, initialize, and use pointers to store memory addresses. A pointer is declared with `*Type` and you get a pointer to a variable using the address operator `&`. To access the value at a pointer's address, you use the dereference operator `*`. Pointers enable efficient passing of large data structures, allow functions to modify original values, and are essential for dynamic memory allocation. Unlike C, Go pointers don't support arithmetic operations, making them safer. Understanding pointer basics is crucial for efficient memory usage and implementing data structures like linked lists and trees.
|
||||
Variables storing memory addresses of other variables. Declared with `*Type`, dereferenced with `*ptr`, address obtained with `&var`. Enable efficient memory usage and allow functions to modify caller's data. Essential for performance and reference semantics.
|
@@ -1,3 +1,3 @@
|
||||
# Pointers with Structs
|
||||
# Pointers with Structs
|
||||
|
||||
Pointers with structs in Go are commonly used to avoid copying large structures and to enable methods to modify struct values. When you have a pointer to a struct, Go provides automatic dereferencing, so you can access fields using dot notation directly (`ptr.field` instead of `(*ptr).field`). Struct pointers are essential for implementing methods that modify the receiver, sharing structs between functions efficiently, and building data structures where structs need to reference each other. Methods can have either value receivers or pointer receivers, with pointer receivers being necessary when the method needs to modify the struct or when the struct is large and copying would be expensive.
|
||||
Pointers to structs enable efficient passing of large structures and allow modification of struct fields. Access fields with `(*ptr).field` or shorthand `ptr.field`. Common for method receivers and when structs need to be modified by functions. Essential for memory efficiency.
|
@@ -1,3 +1,3 @@
|
||||
# Pointers
|
||||
|
||||
Pointers in Go store the memory address of a variable rather than the value itself. They are declared using the `*` operator and you can get the address of a variable using the `&` operator. Pointers allow you to directly modify values in memory, share large data structures efficiently without copying, and enable functions to modify variables passed as arguments. While Go pointers are safer than those in languages like C (no pointer arithmetic), they are essential for understanding how Go manages memory and for writing efficient programs that avoid unnecessary data copying.
|
||||
Variables storing memory addresses of other variables. Enable efficient memory usage and allow functions to modify values. Declared with `*Type`, address obtained with `&`. No pointer arithmetic for safety. Essential for performance and building data structures.
|
@@ -1,3 +1,3 @@
|
||||
# pprof
|
||||
|
||||
pprof is Go's built-in profiling tool that helps identify performance bottlenecks in your applications. It can profile CPU usage, memory allocations, blocking operations, and goroutine activity. You can collect profiles programmatically using the `net/http/pprof` package or through the `go tool pprof` command. The tool generates detailed reports and interactive visualizations showing where your program spends time or allocates memory. Understanding pprof is crucial for optimizing Go applications, diagnosing performance issues, and ensuring efficient resource usage in production environments. It's an essential tool for building high-performance Go applications.
|
||||
Built-in profiling tool for analyzing program performance. Profiles CPU usage, memory allocation, goroutines, blocking operations. Import `net/http/pprof` for web interface or use `go tool pprof` for analysis. Essential for performance optimization and bottleneck identification.
|
@@ -1,3 +1,3 @@
|
||||
# Race Detection
|
||||
|
||||
Race detection is a powerful feature in Go that helps identify race conditions in concurrent programs. A race condition occurs when multiple goroutines access shared memory simultaneously and at least one access is a write. Go's race detector is enabled using the `-race` flag with commands like `go run -race` or `go test -race`. It instruments your code at compile time to detect races at runtime, reporting detailed information about conflicting accesses. The race detector is essential for developing reliable concurrent applications and should be used regularly during development and testing.
|
||||
Built-in tool for detecting race conditions in concurrent programs. Enabled with `-race` flag during build/test/run. Detects unsynchronized access to shared variables from multiple goroutines. Performance overhead in race mode. Essential for debugging concurrent code safety.
|
@@ -1,3 +1,3 @@
|
||||
# regexp
|
||||
|
||||
The `regexp` package provides regular expression functionality for pattern matching and text processing in Go. It implements the RE2 syntax, which is both powerful and safe (guarantees linear time execution). The package supports pattern compilation for performance, various matching methods (match, find, replace), submatch extraction, and both string and byte slice operations. Regular expressions are compiled once and can be reused for better performance. Understanding regular expressions is valuable for text validation, parsing, data extraction, and string manipulation tasks. The Go regexp package prioritizes safety and predictable performance over some advanced features found in other regex engines.
|
||||
Standard library package for regular expression functionality. Implements RE2 syntax for safe, efficient pattern matching. Provides functions for matching, finding, replacing text patterns. Supports compiled expressions for performance. Essential for text processing, validation, parsing.
|
@@ -1,3 +1,3 @@
|
||||
# Select Statement
|
||||
|
||||
The select statement in Go is a powerful control structure that enables non-blocking communication with multiple channels. It allows a goroutine to wait on multiple channel operations simultaneously and execute the case that's ready first. Select can handle send operations, receive operations, and includes a default case for non-blocking behavior when no channels are ready. This makes it essential for implementing timeouts, handling multiple data sources, coordinating between goroutines, and building responsive concurrent systems. The select statement is unique to Go and is fundamental to the language's approach to concurrent programming and channel-based communication.
|
||||
Multiplexer for channel operations. Waits on multiple channel operations simultaneously, executing first one ready. Supports send/receive operations, default case for non-blocking behavior. Essential for coordinating multiple goroutines and implementing timeouts.
|
@@ -1,3 +1,3 @@
|
||||
# Slices
|
||||
|
||||
Slices are dynamic arrays in Go that provide a flexible way to work with sequences of data. Unlike arrays which have a fixed size, slices can grow and shrink as needed. A slice consists of three components: a pointer to an underlying array, a length (number of elements), and a capacity (maximum number of elements). Slices are created using `make()`, slice literals, or by slicing existing arrays or slices. They are reference types, meaning multiple slices can share the same underlying array. Understanding slices is crucial as they are one of the most commonly used data structures in Go.
|
||||
Dynamic arrays built on top of arrays. Reference types with length and capacity. Created with `make()` or slice literals. Support append, copy operations. More flexible than arrays - most commonly used sequence type in Go.
|
@@ -1,3 +1,3 @@
|
||||
# slog
|
||||
|
||||
The `slog` package, introduced in Go 1.21, is the standard library's structured logging solution. It provides fast, structured logging with support for different output formats (text, JSON), log levels (debug, info, warn, error), and contextual attributes. Slog is designed for high performance with minimal allocations and supports both simple and structured logging patterns. It includes features like log level filtering, custom handlers, and integration with the context package for request-scoped logging. Understanding slog is important for building production applications that require comprehensive logging, monitoring, and debugging capabilities while maintaining excellent performance characteristics.
|
||||
Structured logging package introduced in Go 1.21. Provides leveled, structured logging with JSON output support. Better than basic log package for production use. Supports custom handlers, context integration, and performance optimization. Modern replacement for traditional logging.
|
@@ -1,3 +1,3 @@
|
||||
# Standard Library
|
||||
|
||||
Go's standard library is comprehensive and production-ready, providing a wide range of packages for common programming tasks without requiring external dependencies. It includes packages for HTTP servers and clients, JSON handling, file I/O, regular expressions, cryptography, time manipulation, and much more. The standard library is designed with consistency and simplicity in mind, following Go's philosophy of clear, readable code. Learning the standard library is essential for Go developers as it provides the foundation for most applications and demonstrates Go's idiomatic patterns and best practices.
|
||||
Comprehensive collection of packages providing core functionality. Includes I/O, networking, text processing, cryptography, testing, JSON handling, HTTP client/server. Rich ecosystem reducing need for external dependencies. Well-documented, tested, and performance-optimized packages.
|
@@ -1,3 +1,3 @@
|
||||
# Structs
|
||||
|
||||
Structs in Go are custom data types that group together related data fields under a single name. They are similar to classes in other languages but without methods (methods are defined separately). Structs allow you to create complex data models, organize related information, and define the structure of your application's data. You can create instances of structs, access their fields using dot notation, and pass them to functions. Structs are fundamental to Go programming and are often used with interfaces to create flexible, object-oriented designs while maintaining Go's simplicity.
|
||||
Custom data types grouping related fields under single name. Similar to classes but methods defined separately. Create complex data models, organize information, define application data structure. Access fields with dot notation, pass to functions. Fundamental for object-oriented designs.
|
@@ -1,3 +1,3 @@
|
||||
# switch
|
||||
|
||||
The switch statement in Go provides a clean way to compare a variable against multiple values and execute corresponding code blocks. Go's switch is more powerful than in many languages - it doesn't require break statements (no fall-through by default), can switch on any comparable type, supports multiple values per case, and includes expression switches and type switches. Switch statements can also work without an expression, acting like a series of if-else statements. They're more readable than long if-else chains and are essential for clean conditional logic, especially when checking many possible values or implementing state machines.
|
||||
Clean way to compare variable against multiple values and execute corresponding code blocks. No break statements needed (no fall-through by default). Works with any comparable type, supports multiple values per case, expression/type switches. More readable than if-else chains.
|
@@ -1,3 +1,3 @@
|
||||
# `sync` Package
|
||||
# sync Package
|
||||
|
||||
The `sync` package provides basic synchronization primitives for coordinating goroutines and protecting shared resources from race conditions. Key components include Mutex (mutual exclusion locks), RWMutex (read-write locks), WaitGroup (waiting for goroutines to complete), Once (ensuring functions run only once), and Cond (condition variables). These tools are essential for writing safe concurrent programs when channels alone aren't sufficient. While Go encourages communication through channels, the sync package is crucial for scenarios requiring traditional locking mechanisms or synchronizing goroutine lifecycles.
|
||||
Provides synchronization primitives for coordinating goroutines and safe concurrent access. Includes Mutex (mutual exclusion), RWMutex (reader-writer locks), WaitGroup (waiting on goroutines), Once (one-time init). Essential for avoiding race conditions.
|
@@ -1,3 +1,3 @@
|
||||
# `testing` package basics
|
||||
# Testing Package Basics
|
||||
|
||||
The `testing` package is Go's built-in framework for writing and running unit tests, benchmarks, and examples. Tests in Go are written in files ending with `_test.go` and test functions must start with `Test` followed by a capitalized name. The testing package provides a simple yet powerful API with the `*testing.T` type for tests and `*testing.B` for benchmarks. Tests are run using the `go test` command, which automatically discovers and executes test functions. Go's testing philosophy emphasizes simplicity and clarity, making it easy to write comprehensive test suites that ensure code reliability and facilitate refactoring.
|
||||
Standard library package for writing tests. Test functions start with `Test` and take `*testing.T` parameter. Use `t.Error()`, `t.Fatal()` for failures. Test files end with `_test.go`. Run with `go test`. Supports benchmarks and examples.
|
@@ -1,3 +1,3 @@
|
||||
# time
|
||||
|
||||
The `time` package provides functionality for measuring and displaying time, handling durations, and working with timezones. It includes types like `Time` for representing instants in time, `Duration` for representing spans of time, and functions for parsing, formatting, and manipulating temporal data. The package supports timezone-aware operations, time arithmetic, timers, tickers, and various time formats. Understanding the time package is essential for scheduling operations, measuring performance, handling timeouts, and working with timestamps in applications. It's particularly important for building systems that need to handle time-sensitive operations or work across different timezones.
|
||||
Standard library package for time and date operations. Handles parsing, formatting, arithmetic, timers, tickers, and timezone operations. Key types: Time, Duration, Location. Supports RFC3339 format, custom layouts, time zones. Essential for scheduling, timeouts, timestamps.
|
@@ -1,3 +1,3 @@
|
||||
# Type Assertions
|
||||
|
||||
Type assertions in Go provide a way to extract the underlying concrete value from an interface. The syntax `value, ok := interfaceVariable.(ConcreteType)` attempts to assert that the interface holds a value of the specified type. If successful, it returns the value and true; if not, it returns the zero value and false. Without the second return value, a failed type assertion panics. Type assertions are essential when working with empty interfaces (`interface{}`), handling different types in the same function, and implementing type-specific behavior. They're commonly used with type switches for handling multiple possible types efficiently and safely.
|
||||
Extract underlying concrete value from interface. Syntax: `value.(Type)` or `value, ok := value.(Type)` for safe assertion. Panics if type assertion fails without ok form. Essential for working with interfaces and empty interfaces.
|
@@ -1,3 +1,3 @@
|
||||
# Type Switch
|
||||
|
||||
Type switches in Go provide a clean way to perform different actions based on the dynamic type of an interface value. Using the syntax `switch v := interfaceVar.(type)`, you can check multiple types in a single construct and execute type-specific code for each case. Type switches are more efficient and readable than multiple type assertions, especially when handling many possible types. They're commonly used in functions that accept empty interfaces, implementing polymorphic behavior, serialization/deserialization logic, and building flexible APIs that can handle various input types. Type switches make Go's static typing more flexible while maintaining safety and performance.
|
||||
Special form of switch statement that operates on types rather than values. Syntax: `switch v := i.(type)`. Used with interfaces to determine underlying concrete type. Each case specifies types to match. Essential for handling interface{} and polymorphic code.
|
@@ -1,3 +1,3 @@
|
||||
# Variables & Constants
|
||||
|
||||
Variables and constants are fundamental building blocks for storing and managing data in Go programs. Variables hold values that can change during program execution and are declared using `var` keyword or the short declaration operator `:=`. Constants hold values that cannot change and are declared using the `const` keyword. Go supports various declaration styles, type inference, zero values (default values for uninitialized variables), and block-level scope. Understanding how to properly declare, initialize, and use variables and constants is essential for writing any Go program and managing data effectively.
|
||||
Variables store changeable values declared with `var` or `:=` (short declaration). Constants store unchangeable values declared with `const`. Variables can be explicitly typed or use type inference. Constants must be compile-time determinable. Both support block declarations and package/function scope.
|
@@ -1,3 +1,3 @@
|
||||
# Variadic Functions
|
||||
|
||||
Variadic functions in Go can accept a variable number of arguments of the same type using the `...` syntax. The variadic parameter must be the last parameter and is treated as a slice within the function. Examples include `fmt.Printf()` and `append()`. To call a variadic function with a slice, you use the `...` operator to "expand" the slice. Variadic functions are useful for creating flexible APIs, utility functions that work with varying amounts of data, and building wrapper functions. They provide convenience and flexibility while maintaining type safety, making function calls more natural when the number of arguments isn't known at compile time.
|
||||
Functions accepting variable number of arguments of same type. Syntax: `func name(args ...Type)`. Arguments treated as slice inside function. Call with multiple args or slice with `...` operator. Common in functions like `fmt.Printf()` and `append()`.
|
@@ -1,3 +1,3 @@
|
||||
# WaitGroups
|
||||
|
||||
WaitGroups in Go's sync package provide a way to wait for a collection of goroutines to finish executing. A WaitGroup maintains a counter that represents the number of goroutines to wait for. You increment the counter with `Add()`, decrement it with `Done()` (typically called with `defer` in each goroutine), and block until the counter reaches zero with `Wait()`. This is essential for coordinating goroutine completion, ensuring all work is finished before proceeding, and preventing main function exit before goroutines complete. WaitGroups are commonly used in scenarios where you need to process multiple items concurrently and wait for all processing to complete.
|
||||
Synchronization primitive from sync package for waiting on multiple goroutines to complete. Use `Add()` to increment counter, `Done()` when goroutine finishes, `Wait()` to block until counter reaches zero. Essential for coordinating goroutine completion in concurrent programs.
|
@@ -1,3 +1,3 @@
|
||||
# Web Development
|
||||
|
||||
Go is an excellent choice for web development, offering built-in support for HTTP servers, efficient concurrency handling, and a rich ecosystem of web frameworks and libraries. The standard library's `net/http` package provides powerful tools for building web servers, handling HTTP requests and responses, and creating RESTful APIs. Go's performance characteristics, simple deployment model (single binary), and excellent concurrency support make it ideal for building scalable web applications, microservices, and APIs. Whether you use the standard library or popular frameworks, Go provides the tools needed for modern web development.
|
||||
Excellent for web development with built-in HTTP server support, efficient concurrency, rich ecosystem. Standard `net/http` package provides powerful tools for servers, requests/responses, RESTful APIs. Performance, simple deployment (single binary), and concurrency make it ideal for scalable web apps.
|
@@ -1,3 +1,3 @@
|
||||
# With Maps & Slices
|
||||
# Pointers with Maps & Slices
|
||||
|
||||
Maps and slices in Go are reference types, meaning they contain pointers to underlying data structures. When you pass maps or slices to functions, you're passing references rather than copies, so modifications inside functions affect the original data. However, for slices, operations that change length or capacity (like append) may create new underlying arrays, so if you need to modify a slice's length from within a function, you typically need to return the modified slice or pass a pointer to the slice. Understanding this behavior is crucial for effective data manipulation and avoiding common pitfalls when working with these fundamental Go data structures.
|
||||
Maps and slices are reference types - passing them to functions doesn't copy underlying data. Modifications inside functions affect original. No need for explicit pointers. However, reassigning the slice/map variable itself won't affect caller unless using pointer.
|
@@ -1,3 +1,3 @@
|
||||
# Worker Pools
|
||||
|
||||
Worker pools are a concurrency pattern in Go that uses a fixed number of goroutines (workers) to process jobs from a shared queue. This pattern is useful for controlling resource usage, limiting concurrent operations, and efficiently processing large numbers of tasks. Worker pools typically consist of job channels, result channels, and a predetermined number of worker goroutines that continuously process jobs. This approach prevents resource exhaustion that could occur with unlimited goroutine creation and provides predictable performance characteristics. Understanding worker pools is essential for building scalable applications that need to process many concurrent tasks while maintaining control over system resources.
|
||||
Concurrency pattern using fixed number of goroutines to process tasks from shared queue. Controls resource usage while maintaining parallelism. Typically implemented with buffered channels for task distribution and WaitGroups for synchronization. Ideal for CPU-bound tasks and rate limiting.
|
Reference in New Issue
Block a user