Skip to content

Expert · Careers and interviews · topic 43 of 46 · 45 min

Go language interview questions

Explanation

Go interviews check whether you really understand a small set of ideas: slices and their backing arrays, maps, value versus pointer receivers, interfaces and the nil-interface trap, defer order, error wrapping, make versus new, and the garbage collector. Practise explaining each in two or three plain sentences with a tiny code example.

How Go interviews usually run

For Go backend roles you typically meet: a screening call, one or two coding rounds (often allowed in Go), a round on Go concepts and concurrency, and for experienced roles a system design round. Interviewers care less about trivia and more about whether you can explain WHY Go behaves as it does. Below are the questions that come up again and again, with answers you should be able to give in your own words.

1. What is a slice internally? What happens on append?

A slice is a small header: a pointer to an underlying array, a length and a capacity. Slicing shares the array. append writes into the existing array if there is spare capacity; otherwise it allocates a bigger array, copies the elements and returns a header pointing to the new array. That is why you must use append's return value, and why two slices can unexpectedly change each other.

go
s := []int{1, 2, 3}
t := s[:2]        // len 2, cap 3, shares s's array
t = append(t, 4)  // fits in capacity: overwrites s[2]
fmt.Println(s)    // [1 2 4]
The classic slice-aliasing question.

2. Are maps ordered? Are they safe for concurrent use?

No and no. Iteration order is unspecified and randomised on purpose. Concurrent writes (or a write with a concurrent read) are a data race and can crash the program with "concurrent map writes". Protect a shared map with a sync.Mutex or RWMutex; sync.Map suits only special cases. Reading a missing key returns the zero value; use v, ok := m[k] to check presence. Writing to a nil map panics.

3. Value receiver or pointer receiver?

A value receiver gets a copy, so changes are lost; a pointer receiver works on the original. Use pointers when the method mutates, when the struct is large, or when it contains a mutex; keep a type's receivers consistent. Method sets matter for interfaces: methods with pointer receivers belong only to *T, so only *T satisfies an interface that needs them.

4. Why can an error be non-nil when it holds a nil pointer?

An interface value is a pair (dynamic type, value). It is nil only when both are empty. Returning a nil *MyError as an error gives (type *MyError, value nil), which is not equal to nil. Fix: return a literal nil on success.

5. In what order do deferred calls run? When are arguments evaluated?

go
for i := 0; i < 3; i++ {
	defer fmt.Print(i)           // prints 210: LIFO, i copied at defer time
}

for i := 0; i < 3; i++ {
	defer func() { fmt.Print(i) }() // Go 1.22+: 210 (each round has its own i)
}                                   // before Go 1.22: 333 (one shared i)
Last in, first out. Arguments are evaluated when the defer statement runs; closures read variables when they run.

6. How do you handle errors in Go? What are %w, errors.Is and errors.As?

Errors are values returned as the last result and checked right away. Wrap with fmt.Errorf("context: %w", err) to add context while keeping the original. errors.Is(err, target) checks the chain for a specific value (a sentinel such as sql.ErrNoRows); errors.As(err, &target) finds an error of a specific type and gives you its fields. Panic is for bugs, not for expected failures.

7. make versus new

new(T) allocates a zeroed T and returns *T; it works for any type. make is only for slices, maps and channels: it initialises their internal structure and returns the value itself (not a pointer). var m map[string]int is nil and cannot be written; make(map[string]int) can.

8. How does Go's garbage collector work, briefly?

Go uses a concurrent, tri-colour mark-and-sweep collector. Most of the work runs alongside your goroutines, with very short stop-the-world pauses. The compiler's escape analysis keeps many values on the stack, which costs the GC nothing. You can tune it with GOGC (how much the heap may grow between collections, default 100) and GOMEMLIMIT (a soft memory limit, Go 1.19+). To reduce GC work, allocate less: reuse buffers, pre-size slices, avoid needless pointers.

More quick ones

QuestionShort answer
Does Go have inheritance?No. It uses composition via struct embedding, and interfaces for polymorphism.
How does a type implement an interface?Implicitly, by having all its methods. No implements keyword.
Are strings mutable?No. len counts bytes (UTF-8); range gives runes.
What does init() do?Runs automatically before main, after package variables are initialised. Keep it small.
Arrays vs slices?Arrays have fixed size in the type and are copied by value; slices are views that can grow.
What is the blank identifier?_ discards a value, or imports a package only for its side effects.
When were generics added?Go 1.18. Use them for containers and algorithms; use interfaces when behaviour differs.
What is escape analysis?The compiler decides whether a value can live on the stack or must go on the heap.
Tip: Answer with the pattern: one-sentence definition, why it matters, a 3-line example, a common mistake. Interviewers remember candidates who mention the mistake and how to avoid it.
Careful: Do not bluff about version-specific details. "I believe that changed in Go 1.22, let me confirm" is far better than a confident wrong answer.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Go language interview questions · 1/7

Go interview questions

Go interviews focus on a small set of ideas. Know them deeply and explain them simply.

Prefer a video by a teacher? Find free videos on “golang interview questions slices maps interfaces defer explained” on YouTube ↗

In real life: A typical 45-minute Go concepts round

An interviewer at a Bengaluru fintech starts with "explain slices", then shows the aliasing snippet and asks for the output. Next comes "why is my error not nil?" with a typed-nil example, then "value or pointer receiver for a struct with a mutex?". The candidate who explains each with the header/pair/method-set ideas, and writes a 3-line example on the shared editor, moves to the next round.

go
type Account struct {
	mu  sync.Mutex
	bal int64
}

// Interview question: which receiver, and why?
func (a *Account) Deposit(p int64) { // pointer: mutates, and the mutex must not be copied
	a.mu.Lock()
	defer a.mu.Unlock()
	a.bal += p
}
Three concepts in one snippet: pointer receivers, mutexes and defer.

Practice (0/4 done)

Task 1 · Question

What does this print? a := []int{1, 2, 3, 4} b := a[1:3] b = append(b, 9) fmt.Println(a)

Task 2 · Question

Which is true about make and new?

Task 3 · Question

Which GC setting gives the collector a soft memory limit?

Task 4 · Practice

Record yourself (or explain to a friend) answering these five in under 90 seconds each: slices and append, map safety, value vs pointer receivers, the nil error trap, and errors.Is vs errors.As. Each answer must include a tiny code example and one common mistake.

Quick quiz

Question 1

1.How does Go provide polymorphism without inheritance?

Question 2

2.What does escape analysis decide?

Question 3

3.Before Go 1.22, what did for i := 0; i < 3; i++ { defer func() { fmt.Print(i) }() } print?

Question 4

4.What is a good structure for a concept answer?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

How does Go provide polymorphism without inheritance?

Answer: Interfaces satisfied implicitly

Any type with the right methods can be used through an interface.

What does escape analysis decide?

Answer: Whether a value can stay on the stack or must be allocated on the heap

Values that do not escape their function can live on the stack.

Before Go 1.22, what did for i := 0; i < 3; i++ { defer func() { fmt.Print(i) }() } print?

Answer: 333

All closures shared one i, which was 3 when they ran. Since Go 1.22 it prints 210.

What is a good structure for a concept answer?

Answer: Definition, why it matters, tiny example, common mistake

Short, structured answers show real understanding.

Can you do p++ on a pointer in normal Go code?Related

Answer: No, Go has no pointer arithmetic

Pointer arithmetic is not allowed (outside the unsafe package).

From Pointers without fear

Which three things make up a slice header?Related

Answer: Pointer to array, length, capacity

A slice is a pointer, a length and a capacity.

From Slices in depth: length, capacity and sharing

Which verb in fmt.Errorf wraps an error so errors.Is can find it?Related

Answer: %w

%w wraps; %v and %s only copy the text.

From Errors as values: wrap, Is and As

When is an interface value equal to nil?Related

Answer: When both its type and value parts are unset

A typed nil pointer inside an interface still makes the interface non-nil.

From any, type assertions and type switches

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Careers and interviews” before its exam: Concurrency interview questions and coding rounds, Your portfolio project: a production-style Go API, Go careers in India and a 30-day revision plan.
  2. Module 10 exam: Careers and interviews · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. 46 topics left in the course before the final exam.

← Previous: Go in cloud and DevOps: Kubernetes, Terraform and Prometheus