Golang / GoLang Concurrency Mastery Interview Questions
Implement a lock-free stack using atomic CAS operations and explain the ABA problem.
A lock-free data structure uses compare-and-swap (CAS) instead of mutexes β concurrent access without blocking. This is an advanced topic demonstrating deep understanding of memory ordering and Go's atomic package.
// Lock-free stack using atomic.Pointer (Go 1.19+) type node[T any] struct { val T next *node[T] } type LockFreeStack[T any] struct { head atomic.Pointer[node[T]] } func (s *LockFreeStack[T]) Push(val T) { n := &node[T]{val: val} for { old := s.head.Load() // atomic read of current head n.next = old // link new node to current head if s.head.CompareAndSwap(old, n) { return // success: head changed from old to n atomically } // CAS failed: another goroutine modified head; retry } } func (s *LockFreeStack[T]) Pop() (T, bool) { for { old := s.head.Load() if old == nil { var z T; return z, false } if s.head.CompareAndSwap(old, old.next) { return old.val, true } } } // ABA PROBLEM: // Goroutine 1 reads head = A; pauses // Goroutine 2: pops A, pushes B, pops B, pushes A again (same pointer!) // Goroutine 1 resumes: CAS sees head == A Γ’ΒΒ "unchanged" Γ’ΒΒ succeeds // But B has been removed Γ’ΒΒ the stack is now corrupted // WHY GO'S GC PREVENTS THE ABA PROBLEM: // The GC does not reuse memory from a node until ALL pointers to it are gone // If Goroutine 1 holds a reference to node A, A's memory is not recycled // So when CAS sees the same pointer, it is guaranteed to be the same object // Γ’ΒΒ ABA is largely eliminated in GC-managed languages
More Related questions...