Problem Statement
Explain the internal behavior of Go maps, including iteration order, memory management, and concurrent access patterns.
Key Interview Questions
Q1: Is the iteration order of a map deterministic?
m := map[string]int{"a": 1, "b": 2, "c": 3}
for k, v := range m {
fmt.Println(k, v) // Order changes each run!
}Answer: No, iteration order is explicitly randomized by the runtime to prevent developers from relying on it.
Q2: Can you take the address of a map value? e.g., &m["key"]?
m := map[string]int{"a": 1}
// ptr := &m["a"] // COMPILE ERROR!Answer: No. Map growth might move values to new buckets, invalidating pointers.
Q3: What keys can be used in a map?
Answer: Any type that is "comparable" (supports ==). Slices, maps, and functions cannot be keys.
Q4: What happens if you read from a nil map?
var m map[string]int // nil
val := m["key"] // Returns 0 (zero value)Q5: What happens if you write to a nil map?
var m map[string]int // nil
m["key"] = 1 // PANIC: assignment to nil mapQ6: Does delete(map, key) shrink the memory usage?
Answer: No! Buckets remain allocated. You must recreate the map to reclaim memory.
// To truly free memory:
oldMap := m
m = make(map[string]int, len(oldMap)/2)
for k, v := range oldMap {
if shouldKeep(k) {
m[k] = v
}
}Q7: How do you implement a "Set" in Go?
type Set map[string]struct{}
func (s Set) Add(key string) {
s[key] = struct{}{}
}
func (s Set) Has(key string) bool {
_, ok := s[key]
return ok
}Q8: Why use struct{} instead of bool for sets?
Answer: struct{} uses 0 bytes of memory, bool uses 1 byte per entry.
Q9: How do you safely access a map from multiple goroutines?
// Option 1: sync.RWMutex
type SafeMap struct {
mu sync.RWMutex
m map[string]int
}
// Option 2: sync.Map (better for write-once, read-many)
var m sync.Map
m.Store("key", 1)
val, ok := m.Load("key")