Go (Golang) Coding Problems
10 Concurrency, Generics & System Programming Challenges
Document Overview: 10 carefully curated coding challenges designed to evaluate knowledge of language idioms,
concurrency, memory management, algorithmic thinking, and core standard libraries in Go (Golang).
Problem 1: Concurrent Pipeline Word Counter MEDIUM
Implement a pipeline using Go goroutines and channels to read a slice of text strings, tokenize them into words
concurrently, and aggregate total word frequencies using a synchronized structure or a dedicated reducer
channel.
FUNCTION SIGNATURE / INTERFACE:
func ConcurrentWordCount(lines []string, workers int) map[string]int
INPUT / CONTEXT:
Slice of strings: ["go is fast", "concurrency in go", "fast and concurrent"]
EXPECTED OUTPUT:
Map[string]int: {"go": 2, "is": 1, "fast": 2, "concurrency": 1, "in": 1, "and": 1,
"concurrent": 1}
CONSTRAINTS & GUIDANCE:
Must process line tokenization across at least 3 worker goroutines and use channel communication for aggregation.
Page 1 of 6
Problem 2: Worker Pool with Graceful Shutdown MEDIUM
Create a generic worker pool in Go that processes incoming tasks (function executions). The worker pool must
support a context-based graceful cancellation/timeout mechanism, ensuring remaining tasks in queue are
drained or rejected cleanly.
FUNCTION SIGNATURE / INTERFACE:
type Task func(ctx [Link]) error
func RunWorkerPool(ctx [Link], tasks []Task, numWorkers int) []error
INPUT / CONTEXT:
10 task functions, worker pool capacity = 3, Context timeout = 500ms.
EXPECTED OUTPUT:
Processed task IDs and list of uncompleted tasks due to timeout.
CONSTRAINTS & GUIDANCE:
Use [Link], select, [Link], and buffered channels.
Problem 3: LRU Cache with Thread-Safe Generics HARD
Design and implement an in-memory Least Recently Used (LRU) cache in Go using Go 1.18+ Generics (`[K
comparable, V any]`). Ensure thread safety across concurrent reads and writes.
FUNCTION SIGNATURE / INTERFACE:
type LRUCache[K comparable, V any] struct { ... }
func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V]
INPUT / CONTEXT:
Cache capacity = 2. Set(1, "A"), Set(2, "B"), Get(1) [returns "A"], Set(3, "C") [evicts 2].
EXPECTED OUTPUT:
Get(2) returns zero value + false.
CONSTRAINTS & GUIDANCE:
All methods (Get, Put) must operate in O(1) average time complexity using containers/list and [Link].
Page 2 of 6
Problem 4: Custom JSON Unmarshaler for Dynamic Types MEDIUM
Implement custom `[Link]` interface on a custom struct `Event` that decodes polymorphism payloads
depending on a `type` field in the raw JSON payload.
FUNCTION SIGNATURE / INTERFACE:
type Event struct { Type string; Payload interface{} }
func (e *Event) UnmarshalJSON(data []byte) error
INPUT / CONTEXT:
JSON strings containing `{"type": "login", "data": {"user_id": 42}}` vs `{"type": "payment",
"data": {"amount": 99.5}}`.
EXPECTED OUTPUT:
Struct with strongly typed inner field parsed correctly without losing data.
CONSTRAINTS & GUIDANCE:
Must implement `UnmarshalJSON([]byte) error` on the target struct.
Problem 5: Rate Limiter using Token Bucket Algorithm MEDIUM
Build a thread-safe token bucket rate limiter in Go. The rate limiter allows requests up to a specified rate (tokens
per second) and maximum burst capacity.
FUNCTION SIGNATURE / INTERFACE:
type TokenBucket struct { ... }
func NewTokenBucket(rate float64, capacity int) *TokenBucket
func (tb *TokenBucket) Allow() bool
INPUT / CONTEXT:
Capacity = 5, Refill Rate = 2 tokens/sec. 7 rapid calls to Allow().
EXPECTED OUTPUT:
First 5 calls return `true`, next 2 calls return `false` until time elapses.
CONSTRAINTS & GUIDANCE:
Use `[Link]` or timestamp delta calculation with `[Link]`.
Page 3 of 6
Problem 6: Binary Tree Level Order Traversal via Channels EASY
Given a binary tree, traverse its node values level by level from left to right using a channel producer-consumer
model.
FUNCTION SIGNATURE / INTERFACE:
type TreeNode struct { Val int; Left, Right *TreeNode }
func LevelOrder(root *TreeNode) <-chan []int
INPUT / CONTEXT:
Tree: [3, 9, 20, null, null, 15, 7]
EXPECTED OUTPUT:
[ [3], [9, 20], [15, 7] ]
CONSTRAINTS & GUIDANCE:
Generate elements level-by-level through a channel `chan []int` until completed.
Problem 7: In-Memory Key-Value Store with TTL MEDIUM
Build a concurrent-safe key-value store in Go where keys expire after a specified duration (Time-To-Live). Include
a background goroutine cleaner process.
FUNCTION SIGNATURE / INTERFACE:
type TTLStore struct { ... }
func (s *TTLStore) Set(key string, val interface{}, ttl [Link])
func (s *TTLStore) Get(key string) (interface{}, bool)
INPUT / CONTEXT:
Set("session", "xyz", 200*[Link]). Sleep 300ms. Get("session").
EXPECTED OUTPUT:
Get returns `""`, `false`.
CONSTRAINTS & GUIDANCE:
Avoid memory leaks by periodically sweeping expired keys.
Page 4 of 6
Problem 8: File Directory Tree Walker with Fan-Out Fan-In HARD
Write a concurrent directory tree walker that computes the MD5 checksum of every regular file in a directory tree
using fan-out worker routines and fan-in aggregation.
FUNCTION SIGNATURE / INTERFACE:
func ComputeDirHashes(rootDir string) (map[string]string, error)
INPUT / CONTEXT:
Root folder path: "/var/logs"
EXPECTED OUTPUT:
Map of file paths to MD5 checksum hashes.
CONSTRAINTS & GUIDANCE:
Handle file access errors gracefully without halting the entire process.
Problem 9: Slice Rotation and In-Place Manipulation EASY
Rotate an integer slice to the right by `k` steps in-place without allocating an extra slice of size N.
FUNCTION SIGNATURE / INTERFACE:
func Rotate(nums []int, k int)
INPUT / CONTEXT:
slice = [1, 2, 3, 4, 5, 6, 7], k = 3
EXPECTED OUTPUT:
[5, 6, 7, 1, 2, 3, 4]
CONSTRAINTS & GUIDANCE:
O(1) extra memory space constraint.
Page 5 of 6
Problem 10: HTTP Reverse Proxy Middleware with Retry Logic HARD
Implement an `net/http` middleware handler that proxies HTTP requests to a backend server. If the backend
yields HTTP 5xx errors, retry the request up to N times with exponential backoff.
FUNCTION SIGNATURE / INTERFACE:
func RetryProxy(targetURL string, maxRetries int) [Link]
INPUT / CONTEXT:
Incoming HTTP request to endpoint `/api/v1/resource`.
EXPECTED OUTPUT:
HTTP Response forwarding server output or HTTP 503 if all retries fail.
CONSTRAINTS & GUIDANCE:
Must preserve request body across retries using `[Link]` or `[Link]`.
Page 6 of 6