LearningTech

1. What is the difference between concurrency and parallelism in Golang?
  • Concurrency: Multiple tasks start, run, and complete in overlapping time periods.
  • Example: Single-core CPU running multiple goroutines by switching context.
  • Parallelism: Multiple tasks run at exactly the same time using multiple CPU cores.
  • Example: On a quad-core CPU, four goroutines can truly run in parallel.
2. What 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.

3. How do you implement concurrency in Go?

Using:

    <li><strong>Goroutines:</strong> Lightweight threads managed by Go runtime.</li> <li><strong>Channels:</strong> Safe communication pipes between goroutines.</li> <li><strong>sync.WaitGroup:</strong> Waiting for a collection of goroutines to finish.</li> <li><strong>sync.Mutex:</strong> Locking mechanisms for shared data.</li>
go func() {
fmt.Println("Running in goroutine")

}()</code></pre>

4. How do you handle errors in Go?

Go uses explicit error return values, not exceptions.

val, err := someFunc()

if err != nil {

return err

}</code></pre>

Advanced: Use fmt.Errorf() with %w for wrapping, and errors.Is()/errors.As() for checking types.

5. How 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" }</code></pre>

6. How do you optimize the performance of Go code?
    <li>Use goroutines for parallel execution.</li> <li>Avoid unnecessary memory allocations (use pointers for large structs).</li> <li>Use <code>sync.Pool</code> for object reuse to relieve GC pressure.</li> <li>Prefer slices over arrays.</li> <li>Minimize locking scope or prefer atomic operations.</li>

Tools: go test -bench ., pprof (profiling), go build -gcflags "-m" (escape analysis).

7. What is the role of the init() function in Go?
    <li>Automatically executed before <code>main()</code>.</li> <li>Used for package-level setup, initialization, or configuration.</li> <li>Cannot be called manually.</li> <li>A file/package can have multiple init functions.</li>
8. What are dynamic and static types of variable declaration?

Static: Explicit type declaration.

var age int = 10

Dynamic (Inference): Type inferred from value.

age := 10
9. How 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)</code></pre>

10. How to validate user input?

Check values immediately after reading.

if age < 0 {
fmt.Println("Invalid age")

}</code></pre>

11. How to loop input until valid?
for {
fmt.Print("Enter age: ") fmt.Scan(&age) if age > 0 { break }

}</code></pre>

12. How 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)</code></pre>

13. Flag-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)</code></pre>

14. Cobra/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).

15. CLI with colors & spinners

Enhance UX using libraries:

    <li><code>github.com/fatih/color</code>: <code>color.Red("Error!")</code></li> <li><code>github.com/briandowns/spinner</code>: Show activity during long tasks.</li>
16. Save users to JSON file

Use json.MarshalIndent for pretty-printing data to storage.

data, _ := json.MarshalIndent(users, "", "  ")

os.WriteFile("users.json", data, 0644)</code></pre>

17. CRUD operations using JSON

Flow: Read File -> Unmarshal to Struct Slice -> Modify Slice (Append/Delete) -> Marshal -> Write Back.

18. Go + MySQL CLI app

Use the database driver to connect.

import _ "github.com/go-sql-driver/mysql"

db, _ := sql.Open("mysql", "user:pass@/dbname")</code></pre>

19. Token-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.

20. CLI with concurrency

Run background tasks without blocking the UI/Input loop.

go func() {
performBackgroundSync()

}()

// Main CLI loop continues here...</code></pre>

21. What 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.

22. What are Channels?

Typed conduits for synchronization and data transfer between goroutines.

ch := make(chan int)

go func() { ch <- 10 }() // Send

val := <-ch // Receive</code></pre>

23. Buffered 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.

24. Select Statement

Like a switch for channels. Blocks until one of its cases (send/receive) can proceed. Used for handling timeouts or multiple data sources.

25. How 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.

26. Slice vs Array

Array: Fixed length, value type (copying copies entire array).

Slice: Dynamic length, reference type (pointer to underlying array).

27. Preventing 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.

28. Embedding 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
29. go mod & module management

go mod init creates a new module. go.mod tracks dependencies and versions, replacing the old GOPATH system.

30. Use 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).

31. Panic 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.

32. Memory 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.

33. Context Package

Used to carry deadlines, cancellation signals, and request-scoped values across API boundaries and between processes.

34. Escape 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.

35. Rate-limited HTTP client

Use golang.org/x/time/rate.Limiter or a Token Bucket implementation. Call Wait(ctx) before making a request.

© 2025 LearningTech Knowledge Base. All rights reserved.

Questions | Author