A. Go Language Basics
1What is Go programming language, and why is it used?
Go (Golang) is an open-source, statically typed, compiled programming language created at Google.
Used for: High-performance backend services, Cloud-native applications, Microservices, Concurrency-heavy systems, CLI tools, DevOps tools.
Why popular: Extremely fast compilation, Built-in concurrency (goroutines & channels), Simple syntax, No inheritance complexity, Excellent standard library.
Tip: Go is ideal for distributed systems and scalable cloud architecture.
2How do you implement concurrency in Go?
Using:
- Goroutines: Lightweight threads managed by Go runtime.
- Channels: Safe communication pipes between goroutines.
- sync.WaitGroup: Waiting for a collection of goroutines to finish.
- sync.Mutex: Locking mechanisms for shared data.
go func() {
fmt.Println("Running in goroutine")
}()
3How do you handle errors in Go?
Go uses explicit error return values, not exceptions.
val, err := someFunc()
if err != nil {
return err
}
Advanced: Use fmt.Errorf() with %w for wrapping, and errors.Is()/errors.As() for checking types.
4How do you implement interfaces in Go?
Interfaces are implicitly implemented. If a type provides the methods derived in the interface, it implements it (Duck Typing).
type Animal interface {
Speak() string
}
// Dog implicitly implements Animal by having Speak()
func (Dog) Speak() string { return "Woof" }
5How do you optimize the performance of Go code?
- Use goroutines for parallel execution.
- Avoid unnecessary memory allocations (use pointers for large structs).
- Use
sync.Poolfor object reuse to relieve GC pressure. - Prefer slices over arrays.
- Minimize locking scope or prefer atomic operations.
Tools: go test -bench ., pprof (profiling), go build -gcflags "-m" (escape analysis).
6What is the role of the init() function in Go?
- Automatically executed before
main(). - Used for package-level setup, initialization, or configuration.
- Cannot be called manually.
- A file/package can have multiple init functions.
7What are dynamic and static types of variable declaration?
Static: Explicit type declaration.
var age int = 10
Dynamic (Inference): Type inferred from value.
age := 10
B. Go Input / CLI Handling
8How to read multiple inputs in Go?
Using fmt.Scan (space-separated) or bufio (buffered IO).
var name string
var age int
fmt.Scan(&name, &age)
9How to validate user input?
Check values immediately after reading.
if age < 0 {
fmt.Println("Invalid age")
}
10How to loop input until valid?
for {
fmt.Print("Enter age: ")
fmt.Scan(&age)
if age > 0 { break }
}
11How to build a mini CLI app?
Use os.Args for raw arguments, flag for parsing flags, or libraries like Cobra/Viper for robust tools.
name := flag.String("name", "Guest", "User name")
flag.Parse()
fmt.Println("Hello", *name)
C. Code Explanations
12Why does VS Code add package golangtestprojects?
VS Code's Go extension auto-generates the package name based on the folder name you opened. If you opened a folder named golangtestprojects, it assumes that is the package.
13Explain this bufio code snippet
reader := bufio.NewReader(os.Stdin)
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
Explanation:
- Creates a buffered reader connected to Standard Input.
- Reads input bytes until it hits a newline character (Enter key).
strings.TrimSpaceremoves the trailing newline and any surrounding whitespace.
14Why is new user not added to JSON file?
Common Mistake: Checking or writing to the wrong filename definition (e.g., user.json vs users.json).
D. Go CLI Features
15Flag-based CLI
The flag package parses command-line arguments like --port=8080.
port := flag.String("port", "8000", "Server port")
flag.Parse()
fmt.Printf("Starting on %s\n", *port)
16Cobra/Viper based CLI
Cobra is the standard for modern Go CLIs (used by Kubernetes, Docker). It manages commands, subcommands, and flags.
Viper handles configuration management (JSON/YAML files, env vars).
17CLI with colors & spinners
Enhance UX using libraries:
github.com/fatih/color:color.Red("Error!")github.com/briandowns/spinner: Show activity during long tasks.
18Save users to JSON file
Use json.MarshalIndent for pretty-printing data to storage.
data, _ := json.MarshalIndent(users, "", " ")
os.WriteFile("users.json", data, 0644)
19CRUD operations using JSON
Flow: Read File -> Unmarshal to Struct Slice -> Modify Slice (Append/Delete) -> Marshal -> Write Back.
20Go + MySQL CLI app
Use the database driver to connect.
import _ "github.com/go-sql-driver/mysql"
db, _ := sql.Open("mysql", "user:pass@/dbname")
21Token-based menu system
State management in CLI: Variables hold the "logged in" state (token/user struct). The main loop renders different options based on this state.
22CLI with concurrency
Run background tasks without blocking the UI/Input loop.
go func() {
performBackgroundSync()
}()
// Main CLI loop continues here...
E. Data Structures & Algorithms
23Count subarrays with product < k (Sliding Window)
Problem: Given nums[] and k, find number of contiguous subarrays having product less than k.
Algorithm: Sliding Window. Expand right pointer, multiply product. If product >= k, shrink left pointer until valid. Add right - left + 1 to count.
24Why does sliding window work here?
- Product of positive numbers increases as window expands.
- If a window [left, right] is valid, then all subarrays ending at right within that window are also valid.
- This reduces complexity from O(N³) to O(N).
F. Go Advanced Questions
25What is a Goroutine vs Thread?
Goroutine: Managed by Go runtime, starts with small stack (2KB), grows dynamically, multiplexed onto OS threads.
Thread: Managed by OS, fixed large stack (1MB+), expensive context switch.
26What are Channels?
Typed conduits for synchronization and data transfer between goroutines.
ch := make(chan int)
go func() { ch <- 10 }() // Send
val := <-ch // Receive
27Buffered vs Unbuffered Channels
Unbuffered: make(chan int). Synchronous. Sender blocks until Receiver performs receive.
Buffered: make(chan int, 3). Asynchronous until buffer is full. Sender only blocks if buffer is full.
28Select Statement
Like a switch for channels. Blocks until one of its cases (send/receive) can proceed. Used for handling timeouts or multiple data sources.
29How does Go’s Garbage Collector work?
It uses a concurrent, tri-color mark-and-sweep algorithm. It is optimized for low latency (short stop-the-world pauses) rather than raw throughput.
30Slice vs Array
Array: Fixed length, value type (copying copies entire array).
Slice: Dynamic length, reference type (pointer to underlying array).
31Preventing concurrent map writes
Maps are not safe for concurrent use. Use sync.Mutex to lock before access, or use sync.Map for specific high-concurrency read-heavy cases.
32Embedding vs Inheritance
Go favors Composition. Embedding a struct allows utilizing its methods, but it's not "is-a" relationship, it's "has-a" with syntax sugar.
type Car struct { Engine } // Car promotes methods of Engine
33go mod & module management
go mod init creates a new module. go.mod tracks dependencies and versions, replacing the old GOPATH system.
34Use of defer
Schedules a function call to be run after the surrounding function returns. Executed in LIFO order. Common for cleanup (closing files, unlocking mutexes).
35Panic vs Recover
Panic: Stops normal execution, unwinds stack, runs deferred functions. Used for unrecoverable errors.
Recover: Regains control of a panicking goroutine. Only works inside defer.
36Memory Alignment
The CPU reads data in word-sized chunks. Go struct fields are aligned to these boundaries. Proper ordering of struct fields (largest to smallest) can save memory by reducing padding.
37Context Package
Used to carry deadlines, cancellation signals, and request-scoped values across API boundaries and between processes.
Advanced: Golang & Concurrency
38Escape analysis impact
Determines if variables should be on stack or heap. Heap allocation causes GC pressure. Optimization: Keep variables on stack (don't return pointers to local vars if not needed) to reduce GC overhead.
39Rate-limited HTTP client
Use golang.org/x/time/rate.Limiter or a Token Bucket implementation. Call Wait(ctx) before making a request.
Advanced: Architecture
40Hexagonal Architecture (Ports & Adapters)
Separates Domain Logic (core) from Infrastructure (DB, UI, API). Dependencies point inward. Adapters implement Port interfaces.
41API Gateway Patterns
Handles AuthN/AuthZ, Rate Limiting, Routing, Protocol Translation (REST <-> gRPC). Keep logic minimal; don't put business logic in the gateway.
42SAGA Pattern
Manages distributed transactions. Choreography: Events trigger next step. Orchestration: Central coordinator tells services what to do. Use compensating transactions for rollback.
Advanced: Real-Time Systems
43Backpressure
Prevents system overwhelm. mechanisms: Drop messages, Buffer (Queue), or Reject new work (Rate Limit). In Go: limit goroutines or use blocking channel sends.
44Kafka Ordering
Guaranteed only within a partition. Use the same Partition Key for related events (e.g., same UserID) to ensure sequential processing.
Advanced: Cloud & AWS
45EC2 vs Lambda
EC2: Persistent, control over OS, good for long-running, steady-state apps.
Lambda: Event-driven, ephemeral, scales to zero, good for bursty traffic or glue code.
46High Availability Multi-Region
Active-Active (complex data sync) or Active-Passive (easier). Use Global Load Balancer (Route53), Replicated DBs (DynamoDB Global Tables, Aurora Global), and stateless app tiers.