HireHireInterview Quizzes › Golang Developer

Golang Developer Interview Questions

Think you're ready? These are the questions that actually decide Golang Developer interviews. Warm up on Easy — then face the Hard round, where 95% of candidates crumble. 79 questions across 3 levels, instant score, completely free.

79Questions
3Difficulty levels
95%Fail the hard round
FreeInstant score
Easy
Warm-up · 20 Qs
Medium
Practical · 30 Qs
Hard
Brutal · 29 Qs
⚡ Take the Golang Developer quiz — get your score →

The Golang Developer interview questions

Below are the real questions, grouped by difficulty. Expand any one to reveal the correct answer and why — or take the timed quiz for a score you can share. Can you clear the Hard round?

Easy round 20 questions

What is the zero value of a variable declared as var s string?
  • A. nil
  • B. "" (empty string) ✓
  • C. " " (a space)
  • D. undefined
Correct answer: B. The zero value of a string in Go is the empty string "".
What does this print: s := []int{1,2,3}; fmt.Println(len(s), cap(s))?
  • A. 3 3 ✓
  • B. 3 0
  • C. 0 3
  • D. 3 6
Correct answer: A. A slice literal with 3 elements has both length and capacity of 3.
What happens if you read from a nil map, e.g. var m map[string]int; x := m["a"]?
  • A. Panic
  • B. Returns the zero value 0 ✓
  • C. Compile error
  • D. Returns nil
Correct answer: B. Reading from a nil map is safe and returns the value type's zero value; only writing to a nil map panics.
Given func f() (int, error), what is the idiomatic way to handle it?
  • A. v := f()
  • B. v, err := f(); if err != nil { ... } ✓
  • C. try { f() }
  • D. f() catch err
Correct answer: B. Go returns errors as values; the idiom is to capture both and check err against nil.
What does the defer statement do in: defer file.Close()?
  • A. Closes the file immediately
  • B. Schedules Close to run when the surrounding function returns ✓
  • C. Runs Close in a goroutine
  • D. Cancels the Close call
Correct answer: B. defer schedules the call to execute when the enclosing function returns, useful for cleanup.
What happens when you send to an unbuffered channel with no receiver ready?
  • A. The value is dropped
  • B. The send blocks until a receiver is ready ✓
  • C. Panic
  • D. Compile error
Correct answer: B. An unbuffered channel send blocks until another goroutine is ready to receive.
Why does Go require the := operator here: x := 10 instead of var?
  • A. It doesn't; := is short variable declaration with type inference ✓
  • B. := is for constants only
  • C. := reassigns existing variables
  • D. := is required inside functions always
Correct answer: A. := is shorthand that declares and initializes a variable with an inferred type; var is the longer alternative.
What is printed: a := [3]int{1,2,3}; b := a; b[0] = 9; fmt.Println(a[0])?
  • A. 9
  • B. 1 ✓
  • C. 0
  • D. panic
Correct answer: B. Arrays are value types in Go, so b is a copy and modifying it does not affect a.
How do you make a struct field accessible from other packages?
  • A. Prefix it with export
  • B. Start the field name with an uppercase letter ✓
  • C. Use the public keyword
  • D. Declare it as global
Correct answer: B. Go uses capitalization for visibility; an uppercase first letter exports the identifier.
What does the range clause yield: for i, v := range []string{"a","b"}?
  • A. Two values, each element twice
  • B. Index and value of each element ✓
  • C. Value only
  • D. Key and pointer
Correct answer: B. Ranging over a slice yields the index and a copy of the element value at each iteration.
What happens if a goroutine panics and the panic is not recovered?
  • A. Only that goroutine stops
  • B. The whole program crashes ✓
  • C. It is logged and ignored
  • D. The runtime restarts it
Correct answer: B. An unrecovered panic propagates up and terminates the entire program, not just the goroutine.
What is the result of appending beyond capacity: s := make([]int,0,2); s = append(s,1,2,3)?
  • A. Panic
  • B. A new underlying array is allocated and s grows ✓
  • C. Compile error
  • D. Only 2 elements are kept
Correct answer: B. When append exceeds capacity, Go allocates a larger backing array and copies elements over.
In Go, how does a type satisfy an interface?
  • A. By declaring 'implements'
  • B. By implementing all the interface's methods implicitly ✓
  • C. By embedding the interface
  • D. By registering with the runtime
Correct answer: B. Go interfaces are satisfied implicitly: a type implements an interface simply by having its methods.
What does a receiver like func (p *Point) Move() enable that a value receiver does not?
  • A. Faster execution always
  • B. Modifying the original struct's fields ✓
  • C. Access to private methods
  • D. Automatic concurrency
Correct answer: B. A pointer receiver operates on the original value, so mutations persist beyond the method call.
What is the output: fmt.Println(len("héllo")) where the file is UTF-8?
  • A. 5
  • B. 6 ✓
  • C. 4
  • D. depends on locale
Correct answer: B. len on a string returns the number of bytes; é is 2 bytes in UTF-8, making the total 6.
What does select do when multiple channel cases are ready?
  • A. Runs all of them
  • B. Chooses one at random ✓
  • C. Runs the first in source order
  • D. Blocks forever
Correct answer: B. If multiple select cases are ready, one is chosen pseudo-randomly to avoid starvation.
Why won't this compile: var x int = 5; var y int64 = x?
  • A. y must be a pointer
  • B. Go has no implicit numeric conversion; you need int64(x) ✓
  • C. int64 is not a valid type
  • D. x must be a constant
Correct answer: B. Go requires explicit conversion between distinct numeric types, so you must write int64(x).
What is the value of err after: _, err := strconv.Atoi("123")?
  • A. A parse error
  • B. nil ✓
  • C. "123"
  • D. 0
Correct answer: B. "123" is a valid integer, so Atoi succeeds and returns a nil error.
What happens when you close a channel and then try to send on it?
  • A. The send is ignored
  • B. It panics ✓
  • C. It reopens the channel
  • D. It blocks
Correct answer: B. Sending on a closed channel causes a runtime panic; only receives are safe after close.
How do you declare a constant in Go?
  • A. let x = 5
  • B. const x = 5 ✓
  • C. final x = 5
  • D. var const x = 5
Correct answer: B. Constants are declared with the const keyword, e.g. const x = 5.

Medium round 30 questions

You call a function that returns an error, but you only care whether it failed, not the specific value. What is the idiomatic way to handle an error you intend to deliberately ignore?
  • A. Assign it to the blank identifier: `_ = doSomething()` ✓
  • B. Wrap the call in a `recover()` block
  • C. Assign it to a variable named `err` and never read it
  • D. Cast the error to `nil` explicitly
Correct answer: A. Assigning to the blank identifier `_` is the idiomatic Go way to explicitly discard a return value, including an error you intend to ignore.
In a `for range` loop over a slice, you launch a goroutine inside the loop that references the loop variable. In Go 1.22+, what is true about the loop variable's scope?
  • A. The loop variable is shared across all iterations, so all goroutines may see the final value
  • B. Each iteration gets a fresh copy of the loop variable, avoiding the classic capture bug ✓
  • C. Goroutines cannot access loop variables at all without explicit passing
  • D. The loop variable is always nil inside goroutines
Correct answer: B. As of Go 1.22, the loop variable is scoped per-iteration, so each goroutine captures its own copy rather than a shared variable.
You have a `map[string]int` and want to check whether a key exists without confusing a missing key with a stored zero value. What do you do?
  • A. Use `v := m[key]` and check if `v == 0`
  • B. Use the two-value form `v, ok := m[key]` and check `ok` ✓
  • C. Call `len(m[key])` to test presence
  • D. Use `if m[key] != nil`
Correct answer: B. The comma-ok idiom `v, ok := m[key]` returns a boolean `ok` that reliably distinguishes a present key from an absent one, even when the value is the zero value.
A function accepts an `io.Reader`. You want to pass it a string as input to read from. Which is the correct approach?
  • A. Pass the string directly since strings implement io.Reader
  • B. Use `strings.NewReader(s)` to wrap the string ✓
  • C. Convert the string with `[]byte(s)` and pass it directly
  • D. Use `bytes.NewBufferString(s).String()`
Correct answer: B. `strings.NewReader` returns a `*strings.Reader` that implements `io.Reader`, which is the standard way to adapt a string for reader-based APIs.
You want to guarantee a resource (like a file or mutex unlock) is released when a function returns, regardless of which return path is taken. What is the idiomatic mechanism?
  • A. A `defer` statement placed right after acquiring the resource ✓
  • B. A `finally` block at the end of the function
  • C. Calling the cleanup manually before every `return`
  • D. Wrapping the body in `recover()`
Correct answer: A. `defer` schedules a call to run when the surrounding function returns via any path, making it the idiomatic way to ensure cleanup like `Close()` or `Unlock()`.
Two goroutines increment a shared integer counter without synchronization. What does `go run -race` typically report, and what is the correct fix?
  • A. No issue; integer writes are atomic in Go by default
  • B. A data race; fix with a `sync.Mutex` or `sync/atomic` operations ✓
  • C. A deadlock; fix by adding more goroutines
  • D. A compile error; fix by making the counter a global variable
Correct answer: B. Concurrent unsynchronized writes to a shared variable are a data race detectable by the `-race` flag, and the standard fixes are a mutex or the `sync/atomic` package.
You want to run an operation with a timeout so it is cancelled if it exceeds 2 seconds. What is the idiomatic Go approach?
  • A. Start a `time.Sleep(2*time.Second)` in a goroutine and kill the operation
  • B. Use `context.WithTimeout` and pass the context to the operation ✓
  • C. Set a global variable `timeout = 2` and poll it
  • D. Use `runtime.Gosched()` after 2 seconds
Correct answer: B. `context.WithTimeout` creates a context that is automatically cancelled after the duration, and passing it to context-aware operations is the idiomatic cancellation pattern.
You define `type MyError struct{...}` and want it to satisfy the `error` interface. What must you do?
  • A. Add a field named `error` to the struct
  • B. Implement a method `Error() string` on the type ✓
  • C. Embed the built-in `error` type
  • D. Register the type with `errors.Register`
Correct answer: B. The `error` interface requires a single method `Error() string`, so implementing that method makes any type satisfy `error`.
You receive a wrapped error created with `fmt.Errorf("...: %w", err)` and need to check whether the underlying cause is `sql.ErrNoRows`. Which function do you use?
  • A. `errors.Is(err, sql.ErrNoRows)` ✓
  • B. `err == sql.ErrNoRows`
  • C. `reflect.DeepEqual(err, sql.ErrNoRows)`
  • D. `errors.New(err) == sql.ErrNoRows`
Correct answer: A. `errors.Is` walks the wrapped error chain (via `%w`) and reports whether any error in it matches the target, unlike a direct `==` comparison which fails on wrapped errors.
A function reads from a channel in a loop with `for v := range ch`. When does this loop terminate cleanly?
  • A. When the channel value equals nil
  • B. When the channel is closed and drained ✓
  • C. After exactly one receive
  • D. It never terminates and must be broken manually
Correct answer: B. A `for range` over a channel receives values until the channel is closed and all buffered values are drained, at which point the loop ends.
A slice header holds a pointer to the backing array, a length, and which third field?
  • A. The element type
  • B. The capacity ✓
  • C. A hash value
  • D. The current index
Correct answer: B. A slice consists of a pointer, a length, and a capacity.
What does a receive from a closed channel return?
  • A. It blocks forever
  • B. It panics
  • C. The zero value with ok set to false ✓
  • D. A runtime error
Correct answer: C. Receiving from a closed channel yields the element type's zero value and ok=false immediately.
What happens when you write to a nil map?
  • A. The map is created automatically
  • B. The write is a silent no-op
  • C. A runtime panic occurs ✓
  • D. It fails to compile
Correct answer: C. Assigning to a nil map panics at runtime; only reads are safe.
What happens when you send to a full buffered channel?
  • A. It panics
  • B. The send blocks until space is free ✓
  • C. The value is silently dropped
  • D. It returns an error
Correct answer: B. A send on a full buffered channel blocks until a receiver frees space.
When are the arguments to a deferred function evaluated?
  • A. When the function finally returns
  • B. When the defer statement executes ✓
  • C. Lazily on first use
  • D. Only if the deferred call runs
Correct answer: B. Deferred call arguments are evaluated immediately at the defer statement, though the call runs later.
An interface value equals nil only when?
  • A. Its stored value is nil
  • B. Its dynamic type is nil
  • C. Both its dynamic type and value are nil ✓
  • D. It is always non-nil once assigned
Correct answer: C. An interface is nil only if it holds neither a type nor a value; a nil pointer of a concrete type makes it non-nil.
When should sync.WaitGroup.Add typically be called?
  • A. Inside the worker goroutine
  • B. Before starting the goroutine ✓
  • C. After the corresponding Done
  • D. Inside the Wait call
Correct answer: B. Add must run before the goroutine starts to avoid a race with Wait.
What is the iteration order when ranging over a map?
  • A. Insertion order
  • B. Sorted by key
  • C. Unspecified and randomized ✓
  • D. Reverse insertion order
Correct answer: C. Go deliberately randomizes map iteration order across runs.
When a method with a value receiver is invoked, it operates on?
  • A. The original value
  • B. A copy of the receiver ✓
  • C. A pointer to the value
  • D. A nil receiver
Correct answer: B. A value receiver gets a copy, so mutations do not affect the caller's value.
What is the idiomatic Go way to signal a recoverable failure?
  • A. Throw an exception
  • B. Return an error value ✓
  • C. Call panic
  • D. Set a global errno
Correct answer: B. Go conventionally returns an error value as the last return value.
What happens when you send a value to a nil channel?
  • A. It blocks forever ✓
  • B. It panics immediately
  • C. It returns immediately
  • D. It buffers the value
Correct answer: A. Sends (and receives) on a nil channel block forever.
What does ranging over a map guarantee about iteration order?
  • A. No guaranteed order (deliberately randomized) ✓
  • B. Sorted by key
  • C. Insertion order
  • D. Reverse insertion order
Correct answer: A. Go intentionally randomizes map iteration order across runs.
How do buffered and unbuffered channels differ?
  • A. There is no real difference
  • B. Unbuffered blocks until a receiver is ready; buffered allows sends up to capacity ✓
  • C. Buffered channels are always slower
  • D. Unbuffered channels never block
Correct answer: B. An unbuffered send blocks until a receiver is ready, while a buffered channel accepts sends until its capacity is full.
What do len and cap return for a slice?
  • A. len = element count, cap = allocated capacity ✓
  • B. They are always equal
  • C. cap = length, len = capacity
  • D. cap returns a pointer
Correct answer: A. len is the number of elements, cap is the capacity of the underlying array from the slice's start.
When are the arguments to a deferred call evaluated?
  • A. At the time the defer statement executes ✓
  • B. When the function returns
  • C. Only if a panic occurs
  • D. They are never evaluated
Correct answer: A. Deferred call arguments are evaluated immediately when the defer statement runs, not when the deferred call executes.
Which statement about Go interfaces is true?
  • A. They are satisfied implicitly (structural typing) ✓
  • B. They require an explicit implements clause
  • C. The implementer must be in the same package
  • D. They cannot declare methods
Correct answer: A. A type satisfies an interface simply by implementing its methods; there is no implements keyword.
What triggers a fatal 'all goroutines are asleep - deadlock' error?
  • A. Every goroutine is blocked with none able to proceed ✓
  • B. Too many goroutines are spawned
  • C. A nil pointer is dereferenced
  • D. A slice index is out of range
Correct answer: A. The runtime reports a deadlock when all goroutines are blocked (e.g., an unbuffered send with no receiver).
What happens when append grows a slice beyond its capacity?
  • A. A new, larger underlying array is allocated and copied ✓
  • B. It panics
  • C. The original array always grows in place
  • D. It is a compile error
Correct answer: A. When capacity is exceeded, append allocates a new backing array, copies elements, and returns the new slice.
How do you safely increment a counter shared across goroutines?
  • A. Use a sync.Mutex or atomic operations ✓
  • B. Use a plain global variable
  • C. Store it in a slice
  • D. Wrap it in defer
Correct answer: A. sync.Mutex or the sync/atomic package prevents data races on shared state.
What does the comma-ok form v, ok := m[key] provide for a map?
  • A. ok indicates whether the key exists ✓
  • B. ok is always true
  • C. v is a pointer to the value
  • D. ok holds the value itself
Correct answer: A. The second return value ok is true only if the key was present in the map.

Hard round 29 questions

You have this code: ```go func do() error { var p *MyError // MyError implements error if false { p = &MyError{} } return p } func main() { if err := do(); err != nil { fmt.Println("got error") } else { fmt.Println("no error") } } ``` What prints, and why?
  • A. "no error", because a nil *MyError returned as error is a nil interface
  • B. "got error", because the returned interface holds a non-nil type descriptor even though its value pointer is nil ✓
  • C. A compile error, because you cannot return a typed nil as an error interface
  • D. A panic at runtime when err is compared to nil
Correct answer: B. An interface is a (type, value) pair; assigning a typed nil *MyError makes the type word non-nil, so the interface != nil even though the underlying pointer is nil.
In Go 1.21 (before the 1.22 loop-variable change), this runs: ```go var wg sync.WaitGroup for i := 0; i < 3; i++ { wg.Add(1) go func() { defer wg.Done(); fmt.Print(i) }() } wg.Wait() ``` What is the most accurate statement about its output?
  • A. It always prints exactly "012" in order
  • B. It reliably prints "333" every run
  • C. It commonly prints "333" but the exact digits are unspecified because all goroutines share one i whose final value is 3 and scheduling is nondeterministic ✓
  • D. It is a compile error because i is captured by reference
Correct answer: C. Pre-1.22 all closures capture the same i, which reaches 3 after the loop; output is nondeterministic but typically "333" since goroutines usually run after the loop completes.
Consider: ```go a := []int{1, 2, 3, 4} b := a[:2] b = append(b, 99) fmt.Println(a) ``` What does this print?
  • A. [1 2 3 4]
  • B. [1 2 99 4] ✓
  • C. [1 2 99]
  • D. [1 2 3 4 99]
Correct answer: B. b shares a's backing array with len 2 but cap 4, so append writes 99 into index 2 in place, overwriting the original 3.
A service shows steadily rising memory and `runtime.NumGoroutine()` climbing without bound. The suspect code: ```go func fetch(ctx context.Context) int { ch := make(chan int) go func() { ch <- expensive() }() select { case v := <-ch: return v case <-ctx.Done(): return -1 } } ``` What is the leak and the minimal fix?
  • A. No leak; the goroutine is garbage collected once fetch returns
  • B. On ctx cancellation the goroutine blocks forever on the unbuffered send; make ch buffered with capacity 1 so the send always completes ✓
  • C. The leak is expensive() being slow; wrap it in a timeout instead
  • D. Add defer close(ch) in fetch so the goroutine's send unblocks
Correct answer: B. When ctx.Done fires first, no one ever receives from the unbuffered ch, so the sender blocks permanently; a capacity-1 buffer lets the send complete and the goroutine exit.
Which statement about a nil pointer receiver is correct? ```go type T struct{ v int } func (t *T) Ping() string { return "pong" } func (t *T) Val() int { return t.v } ```
  • A. Calling Ping on a nil *T panics because the receiver is nil
  • B. Calling Ping on a nil *T works, but calling Val on a nil *T panics when it dereferences t.v ✓
  • C. Both Ping and Val panic on a nil *T
  • D. Neither panics; t.v on a nil receiver returns the zero value safely
Correct answer: B. A method call on a nil pointer receiver is legal; it only panics if the body dereferences the pointer, so Ping is safe but Val's access to t.v faults.
Two goroutines run concurrently with no synchronization: ```go m := map[int]int{} go func() { for i := 0; i < 1000; i++ { m[i] = i } }() go func() { for i := 0; i < 1000; i++ { m[i] = -i } }() ``` What is the defined behavior?
  • A. The map ends up with some interleaved mix of values but never crashes
  • B. The Go runtime may detect concurrent map writes and deliberately panic with "concurrent map writes" ✓
  • C. It always produces a data-race compile error without -race
  • D. Writes are serialized internally by a built-in map lock, so it is safe
Correct answer: B. Go maps are not concurrency-safe and the runtime intentionally detects concurrent access, calling fatal("concurrent map writes") to fail loudly rather than corrupt silently.
What does this print? ```go func f() (result int) { defer func() { result *= 2 }() result = 5 return 10 } fmt.Println(f()) ```
  • A. 10
  • B. 20 ✓
  • C. 5
  • D. 15
Correct answer: B. return 10 sets the named return value result to 10, then the deferred closure runs and doubles it to 20 before the function actually returns.
You need a cache read heavily, written rarely, with keys of one type, from many goroutines. For lowest overhead in the read-dominated steady state, which choice is best and why?
  • A. sync.Map, because it is always faster than a mutex-guarded map
  • B. A plain map guarded by sync.Mutex, because mutexes are cheaper than atomics
  • C. A plain map guarded by sync.RWMutex, allowing concurrent readers while still serializing the rare writes ✓
  • D. An unsynchronized map, since rare writes make races unlikely
Correct answer: C. An RWMutex lets many readers proceed in parallel and only blocks for the infrequent writes, which fits a read-heavy homogeneous-key workload better than the interface-boxing and dual-store overhead of sync.Map.
Regarding escape analysis, which scenario forces the value to be heap-allocated? ```go // A func a() int { x := 42; return x } // B func b() *int { x := 42; return &x } // C func c() { x := 42; _ = x } ```
  • A. A, because returning a value copies it to the heap
  • B. B, because the address of x outlives the stack frame so it must escape to the heap ✓
  • C. C, because unused locals are heap-allocated
  • D. None; Go always stack-allocates locals declared with :=
Correct answer: B. Returning &x means the pointer outlives b's frame, so escape analysis moves x to the heap; a and c keep x on the stack.
In a select with multiple ready cases: ```go select { case <-a: // ... case <-b: // ... default: // ... } ``` Which statement is precisely correct?
  • A. Cases are evaluated top-to-bottom, so a wins whenever both a and b are ready
  • B. If both a and b are ready, one is chosen uniformly at random; default runs only when neither a nor b is ready ✓
  • C. default is chosen whenever it is present, making the select non-blocking always
  • D. The select blocks until all channels are ready
Correct answer: B. When several non-default cases are ready select picks one at pseudo-random (no priority), and the default clause only executes when no other case can proceed immediately.
What does GOMAXPROCS control?
  • A. The maximum number of goroutines
  • B. The number of OS threads executing Go code simultaneously ✓
  • C. The default goroutine stack size
  • D. The number of GC worker threads
Correct answer: B. GOMAXPROCS sets how many Ps (and thus OS threads) can run Go code in parallel.
How do goroutine stacks behave regarding size?
  • A. Fixed at 1 MB each
  • B. Start small and grow or shrink dynamically ✓
  • C. Share a single main stack
  • D. Fully preallocated on the heap
Correct answer: B. Goroutine stacks begin small (a few KB) and are resized dynamically as needed.
What does a select statement do when no case is ready and there is no default?
  • A. It panics
  • B. It returns immediately
  • C. It blocks until a case becomes ready ✓
  • D. It busy-loops spinning
Correct answer: C. Without a default, select blocks until one of its communications can proceed.
How does the Go race detector find data races?
  • A. Purely static source analysis
  • B. Runtime instrumentation of memory accesses ✓
  • C. Inspecting held mutexes only
  • D. Compile-time type checking
Correct answer: B. The race detector instruments memory accesses at runtime to observe conflicting unsynchronized access.
When a context is cancelled, what happens to its Done channel?
  • A. It receives a cancellation value
  • B. It is closed ✓
  • C. It is set to nil
  • D. It is garbage collected
Correct answer: B. Cancelling a context closes its Done channel, unblocking all receivers.
Appending to a slice can mutate the original backing array when?
  • A. len equals cap
  • B. len is less than cap ✓
  • C. Always, regardless of capacity
  • D. Never under any condition
Correct answer: B. If len < cap, append writes into the existing backing array shared with other slices.
What is true about copying a sync.Mutex value after it has been used?
  • A. It is always safe
  • B. It yields an independent lock that breaks the mutex invariants ✓
  • C. It performs a deep copy of the lock state atomically
  • D. The compiler prevents it entirely
Correct answer: B. Copying a Mutex duplicates its internal state, producing separate locks that no longer provide mutual exclusion.
What does the Go compiler's escape analysis determine?
  • A. Whether a variable lives on the stack or the heap ✓
  • B. Whether a goroutine can be inlined
  • C. Which variables become GC roots
  • D. Whether values fit in CPU registers
Correct answer: A. Escape analysis decides whether a value can stay on the stack or must be heap-allocated.
Which best describes Go's garbage collector?
  • A. Generational copying collector
  • B. Reference counting
  • C. Concurrent tri-color mark-and-sweep ✓
  • D. Stop-the-world compacting collector
Correct answer: C. Go uses a concurrent, non-generational tri-color mark-and-sweep collector.
When does iota reset to 0?
  • A. At the start of each new line
  • B. At the start of each const block ✓
  • C. Once at package initialization
  • D. It never resets, only increments
Correct answer: B. iota resets to 0 whenever a new const declaration block begins and increments per ConstSpec within it.
In Go's memory model, what makes one goroutine's writes visible to another?
  • A. Sharing the variable alone
  • B. Channel operations or sync primitives that establish happens-before ✓
  • C. Calling time.Sleep between them
  • D. Relying on goroutine scheduling
Correct answer: B. Visibility requires a happens-before edge, created by channel ops, mutexes, or other sync primitives.
What is a typical cause of a goroutine leak?
  • A. A goroutine blocked forever on a channel that never proceeds ✓
  • B. Using defer inside a loop
  • C. Using a WaitGroup
  • D. Closing a channel
Correct answer: A. A goroutine permanently blocked on a channel send/receive is never collected, leaking memory.
What does receiving from a closed channel yield?
  • A. A panic
  • B. It blocks forever
  • C. The zero value with ok=false once drained ✓
  • D. The last value repeated
Correct answer: C. After buffered values are drained, receives on a closed channel return the zero value with ok=false without blocking.
What happens if you send to a closed channel?
  • A. It blocks
  • B. It returns the zero value
  • C. It is a no-op
  • D. It panics ✓
Correct answer: D. Sending on a closed channel causes a runtime panic.
What does Go's garbage collector write barrier primarily enable?
  • A. Concurrent marking while mutators keep running ✓
  • B. Faster memory allocation
  • C. Automatic stack shrinking
  • D. Escape analysis
Correct answer: A. The write barrier tracks pointer writes so the GC can mark concurrently without long stop-the-world pauses.
What is escape analysis in the Go compiler?
  • A. Detecting goroutine leaks
  • B. Deciding whether a variable can stay on the stack or must go to the heap ✓
  • C. Analyzing panic propagation
  • D. Unrolling loops
Correct answer: B. Escape analysis determines if a value's lifetime escapes its function, requiring heap allocation instead of the stack.
What happens if sync.WaitGroup.Done() is called more times than Add()?
  • A. It panics because the counter goes negative ✓
  • B. It blocks
  • C. It is a no-op
  • D. It resets the counter to zero
Correct answer: A. Decrementing the WaitGroup counter below zero triggers a panic.
How do the method sets of value type T and pointer *T differ?
  • A. *T's method set includes pointer-receiver methods; T's does not ✓
  • B. Both method sets are identical
  • C. T includes pointer-receiver methods
  • D. Neither includes value-receiver methods
Correct answer: A. A *T method set contains both value- and pointer-receiver methods, while T's set contains only value-receiver methods.
What does cancelling a context.Context propagate to?
  • A. Its derived child contexts and their Done channels ✓
  • B. Only the parent context
  • C. Every goroutine in the program
  • D. The garbage collector
Correct answer: A. Cancellation flows down to all contexts derived from it, closing their Done channels.

Prep for another role

Questions are original, written and independently verified for HireHire's role interview quizzes. They reflect the kind of knowledge Golang Developer interviews test, not any specific company's questions. HireHire maps live tech & IT jobs across India, updated regularly. Last updated: August 2026.