Top 40 Golang Coding Questions 2026 With Solutions

What changed in 2026 drives
Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.
What I'd actually study for this
- 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
- 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
- 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
- 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken
Where most candidates trip up
The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.
Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.
Last Updated: June 2026 | Level: Freshers to 3 Years | Read Time: ~25 min
These 40 Go coding problems are drawn from public preparation resources and candidate-reported interview experiences at Razorpay, Swiggy, ShareChat, and similar product companies that run Go microservices in production. Candidates report that these problem types appear in technical screening rounds. Each problem has a working Go solution with time and space complexity notes.
Pair with Go Interview Questions 2026 for theory + Python Interview Questions 2026 for language comparison.
Table of Contents
- Arrays and Slices (Q1-Q10)
- Strings and Runes (Q11-Q18)
- Maps and Structs (Q19-Q25)
- Concurrency Problems (Q26-Q33)
- Classic DSA in Go (Q34-Q40)
- Mock Set: 5 Problems
Arrays and Slices
Q1. Find the two numbers in a slice that sum to a target. Easy
func twoSum(nums []int, target int) (int, int) {
seen := make(map[int]int) // value -> index
for i, n := range nums {
complement := target - n
if j, ok := seen[complement]; ok {
return j, i
}
seen[n] = i
}
return -1, -1
}
// Test
fmt.Println(twoSum([]int{2, 7, 11, 15}, 9)) // 0 1
Time: O(n) | Space: O(n)
Q2. Rotate a slice left by k positions. Easy
func rotateLeft(nums []int, k int) []int {
n := len(nums)
k = k % n
return append(nums[k:], nums[:k]...)
}
fmt.Println(rotateLeft([]int{1, 2, 3, 4, 5}, 2)) // [3 4 5 1 2]
Time: O(n) | Space: O(n)
Q3. Remove duplicates from a sorted slice in-place. Easy
func removeDuplicates(nums []int) int {
if len(nums) == 0 {
return 0
}
write := 1
for read := 1; read < len(nums); read++ {
if nums[read] != nums[read-1] {
nums[write] = nums[read]
write++
}
}
return write
}
nums := []int{1, 1, 2, 3, 3, 4}
n := removeDuplicates(nums)
fmt.Println(nums[:n]) // [1 2 3 4]
Time: O(n) | Space: O(1)
Q4. Find the maximum subarray sum (Kadane's algorithm). Medium
func maxSubArray(nums []int) int {
maxSum, curSum := nums[0], nums[0]
for _, n := range nums[1:] {
if curSum < 0 {
curSum = n
} else {
curSum += n
}
if curSum > maxSum {
maxSum = curSum
}
}
return maxSum
}
fmt.Println(maxSubArray([]int{-2, 1, -3, 4, -1, 2, 1, -5, 4})) // 6
Time: O(n) | Space: O(1)
Q5. Merge two sorted slices. Easy
func mergeSorted(a, b []int) []int {
result := make([]int, 0, len(a)+len(b))
i, j := 0, 0
for i < len(a) && j < len(b) {
if a[i] <= b[j] {
result = append(result, a[i])
i++
} else {
result = append(result, b[j])
j++
}
}
result = append(result, a[i:]...)
result = append(result, b[j:]...)
return result
}
fmt.Println(mergeSorted([]int{1, 3, 5}, []int{2, 4, 6})) // [1 2 3 4 5 6]
Time: O(m+n) | Space: O(m+n)
Q6. Find all pairs in a slice with a given difference. Medium
func pairsWithDiff(nums []int, diff int) [][2]int {
set := make(map[int]bool)
for _, n := range nums {
set[n] = true
}
var result [][2]int
for _, n := range nums {
if set[n+diff] {
result = append(result, [2]int{n, n + diff})
}
}
return result
}
fmt.Println(pairsWithDiff([]int{1, 5, 3, 4, 2}, 2)) // [[1 3] [3 5] [2 4]]
Time: O(n) | Space: O(n)
Q7. Find the missing number in a slice [1..n]. Easy
func missingNumber(nums []int) int {
n := len(nums)
expected := n * (n + 1) / 2
actual := 0
for _, v := range nums {
actual += v
}
return expected - actual
}
fmt.Println(missingNumber([]int{3, 0, 1})) // 2
Time: O(n) | Space: O(1)
Q8. Flatten a 2D slice. Easy
func flatten(matrix [][]int) []int {
var result []int
for _, row := range matrix {
result = append(result, row...)
}
return result
}
fmt.Println(flatten([][]int{{1, 2}, {3, 4}, {5, 6}})) // [1 2 3 4 5 6]
Time: O(nm) | Space: O(nm)
Q9. Chunk a slice into groups of size k. Easy
func chunk(nums []int, k int) [][]int {
var result [][]int
for i := 0; i < len(nums); i += k {
end := i + k
if end > len(nums) {
end = len(nums)
}
result = append(result, nums[i:end])
}
return result
}
fmt.Println(chunk([]int{1, 2, 3, 4, 5, 6, 7}, 3)) // [[1 2 3] [4 5 6] [7]]
Q10. Predict the output: slice capacity trap. Medium
package main
import "fmt"
func main() {
s := make([]int, 3, 5)
s[0], s[1], s[2] = 1, 2, 3
t := s[:5]
t[3] = 99
fmt.Println(len(s), cap(s), s)
}
Output: 3 5 [1 2 3]
Explanation: t extends into the existing capacity but s still has length 3. s does not see t[3]=99 because that index is beyond len(s) even though they share the same backing array. len(s) remains 3.
Strings and Runes
Q11. Check if a string is a palindrome. Easy
func isPalindrome(s string) bool {
runes := []rune(s) // handle Unicode
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
if runes[i] != runes[j] {
return false
}
}
return true
}
fmt.Println(isPalindrome("racecar")) // true
fmt.Println(isPalindrome("hello")) // false
Key: Use []rune not []byte for correct Unicode handling.
Q12. Count the frequency of each character. Easy
func charFrequency(s string) map[rune]int {
freq := make(map[rune]int)
for _, ch := range s {
freq[ch]++
}
return freq
}
fmt.Println(charFrequency("hello")) // map[e:1 h:1 l:2 o:1]
Q13. Reverse words in a sentence. Easy
func reverseWords(s string) string {
words := strings.Fields(s) // splits on any whitespace
for i, j := 0, len(words)-1; i < j; i, j = i+1, j-1 {
words[i], words[j] = words[j], words[i]
}
return strings.Join(words, " ")
}
fmt.Println(reverseWords("hello world foo")) // "foo world hello"
Q14. Find the first non-repeating character. Medium
func firstNonRepeating(s string) rune {
freq := make(map[rune]int)
order := []rune{}
for _, ch := range s {
if freq[ch] == 0 {
order = append(order, ch)
}
freq[ch]++
}
for _, ch := range order {
if freq[ch] == 1 {
return ch
}
}
return -1
}
fmt.Println(string(firstNonRepeating("aabbcd"))) // c
Time: O(n) | Space: O(k) where k is the alphabet size
Q15. Check if two strings are anagrams. Easy
func isAnagram(a, b string) bool {
if len(a) != len(b) {
return false
}
freq := make(map[rune]int)
for _, ch := range a {
freq[ch]++
}
for _, ch := range b {
freq[ch]--
if freq[ch] < 0 {
return false
}
}
return true
}
fmt.Println(isAnagram("listen", "silent")) // true
Q16. Longest substring without repeating characters. Medium
func lengthOfLongestSubstring(s string) int {
last := make(map[rune]int)
maxLen, start := 0, 0
for i, ch := range s {
if idx, ok := last[ch]; ok && idx >= start {
start = idx + 1
}
last[ch] = i
if i-start+1 > maxLen {
maxLen = i - start + 1
}
}
return maxLen
}
fmt.Println(lengthOfLongestSubstring("abcabcbb")) // 3
Time: O(n) | Space: O(k)
Q17. Count vowels and consonants. Easy
func countVowelsConsonants(s string) (vowels, consonants int) {
s = strings.ToLower(s)
for _, ch := range s {
if ch >= 'a' && ch <= 'z' {
if strings.ContainsRune("aeiou", ch) {
vowels++
} else {
consonants++
}
}
}
return
}
v, c := countVowelsConsonants("Hello World")
fmt.Println(v, c) // 3 7
Q18. Implement string compression (run-length encoding). Medium
func compress(s string) string {
if len(s) == 0 {
return s
}
var sb strings.Builder
runes := []rune(s)
count := 1
for i := 1; i <= len(runes); i++ {
if i < len(runes) && runes[i] == runes[i-1] {
count++
} else {
sb.WriteRune(runes[i-1])
if count > 1 {
sb.WriteString(strconv.Itoa(count))
}
count = 1
}
}
result := sb.String()
if len(result) >= len(s) {
return s
}
return result
}
fmt.Println(compress("aabbbcccc")) // a2b3c4
fmt.Println(compress("abc")) // abc (no compression benefit)
Maps and Structs
Q19. Group words by their anagram key. Medium
func groupAnagrams(words []string) [][]string {
groups := make(map[string][]string)
for _, w := range words {
runes := []rune(w)
sort.Slice(runes, func(i, j int) bool { return runes[i] < runes[j] })
key := string(runes)
groups[key] = append(groups[key], w)
}
result := make([][]string, 0, len(groups))
for _, g := range groups {
result = append(result, g)
}
return result
}
Q20. Implement an LRU cache. Hard
type LRUCache struct {
cap int
cache map[int]*Node
head *Node
tail *Node
}
type Node struct {
key, val int
prev, next *Node
}
func NewLRU(cap int) *LRUCache {
head, tail := &Node{}, &Node{}
head.next = tail
tail.prev = head
return &LRUCache{cap: cap, cache: make(map[int]*Node), head: head, tail: tail}
}
func (l *LRUCache) remove(n *Node) {
n.prev.next = n.next
n.next.prev = n.prev
}
func (l *LRUCache) addFront(n *Node) {
n.next = l.head.next
n.prev = l.head
l.head.next.prev = n
l.head.next = n
}
func (l *LRUCache) Get(key int) int {
if n, ok := l.cache[key]; ok {
l.remove(n)
l.addFront(n)
return n.val
}
return -1
}
func (l *LRUCache) Put(key, val int) {
if n, ok := l.cache[key]; ok {
l.remove(n)
n.val = val
l.addFront(n)
return
}
if len(l.cache) >= l.cap {
lru := l.tail.prev
l.remove(lru)
delete(l.cache, lru.key)
}
n := &Node{key: key, val: val}
l.cache[key] = n
l.addFront(n)
}
Time: O(1) get and put | Space: O(capacity)
Q21. Count words in a string using a map. Easy
func wordCount(s string) map[string]int {
counts := make(map[string]int)
for _, w := range strings.Fields(s) {
counts[strings.ToLower(w)]++
}
return counts
}
Q22. Deep copy a map of string slices. Medium
func deepCopyMap(m map[string][]int) map[string][]int {
result := make(map[string][]int, len(m))
for k, v := range m {
cp := make([]int, len(v))
copy(cp, v)
result[k] = cp
}
return result
}
Key: copy is required because slice assignment would share the backing array.
Q23. Invert a map (value -> key). Easy
func invertMap(m map[string]int) map[int]string {
result := make(map[int]string, len(m))
for k, v := range m {
result[v] = k
}
return result
}
If multiple keys map to the same value, the last one wins. Consider returning map[int][]string for a safe inversion.
Q24. Implement a stack using a slice. Easy
type Stack[T any] struct{ items []T }
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
var zero T
if len(s.items) == 0 { return zero, false }
n := len(s.items) - 1
v := s.items[n]
s.items = s.items[:n]
return v, true
}
func (s *Stack[T]) Peek() (T, bool) {
var zero T
if len(s.items) == 0 { return zero, false }
return s.items[len(s.items)-1], true
}
Q25. Predict the output: map iteration order. Easy
package main
import "fmt"
func main() {
m := map[string]int{"a": 1, "b": 2, "c": 3}
keys := make([]string, 0)
for k := range m {
keys = append(keys, k)
}
fmt.Println(keys)
}
Output: [a b c] in unspecified order (non-deterministic)
Explanation: Go map iteration order is intentionally randomized. Never rely on insertion order. Sort keys explicitly for deterministic output.
Concurrency Problems
Q26. Implement a concurrent word counter. Medium
func concurrentWordCount(texts []string) int {
counts := make(chan int, len(texts))
for _, text := range texts {
go func(t string) {
counts <- len(strings.Fields(t))
}(text)
}
total := 0
for range texts {
total += <-counts
}
return total
}
Q27. Rate limiter using a ticker channel. Advanced
func rateLimiter(requests []string, rate time.Duration) {
tick := time.NewTicker(rate)
defer tick.Stop()
for _, req := range requests {
<-tick.C
fmt.Printf("processing %s at %s\n", req, time.Now().Format("15:04:05.000"))
}
}
// rateLimiter([]string{"req1","req2","req3"}, 200*time.Millisecond)
Q28. Implement a timeout with select. Medium
func withTimeout(fn func() string, timeout time.Duration) (string, error) {
result := make(chan string, 1)
go func() {
result <- fn()
}()
select {
case v := <-result:
return v, nil
case <-time.After(timeout):
return "", fmt.Errorf("operation timed out after %v", timeout)
}
}
Q29. Merge multiple channels into one (fan-in). Advanced
func fanIn(channels ...<-chan int) <-chan int {
merged := make(chan int)
var wg sync.WaitGroup
for _, ch := range channels {
wg.Add(1)
go func(c <-chan int) {
defer wg.Done()
for v := range c {
merged <- v
}
}(ch)
}
go func() {
wg.Wait()
close(merged)
}()
return merged
}
Q30. Semaphore pattern with a buffered channel. Advanced
// Limit concurrent database connections to 5
sem := make(chan struct{}, 5)
func queryDB(id int) {
sem <- struct{}{} // acquire
defer func() { <-sem }() // release
// expensive DB operation
fmt.Printf("query %d running\n", id)
time.Sleep(100 * time.Millisecond)
}
Q31. Implement once-run with sync.Once. Medium
var (
once sync.Once
instance *Config
)
type Config struct{ DSN string }
func GetConfig() *Config {
once.Do(func() {
fmt.Println("initializing config")
instance = &Config{DSN: os.Getenv("DATABASE_URL")}
})
return instance
}
Even when called from 100 goroutines simultaneously, the init block runs exactly once.
Q32. Predict the output: goroutine closure capture. Advanced
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(i)
}()
}
wg.Wait()
}
Output: 3 3 3 (or similar, all printing 3)
Explanation: All three goroutines capture the same variable i. By the time they execute, the loop has finished and i=3. Fix: pass i as a parameter go func(i int) {...}(i).
Q33. Graceful HTTP server shutdown. Advanced
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", handler)
srv := &http.Server{Addr: ":8080", Handler: mux}
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatal(err)
}
}()
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal(err)
}
fmt.Println("server shut down gracefully")
}
Classic DSA in Go
Q34. Binary search. Easy
func binarySearch(nums []int, target int) int {
lo, hi := 0, len(nums)-1
for lo <= hi {
mid := lo + (hi-lo)/2
switch {
case nums[mid] == target:
return mid
case nums[mid] < target:
lo = mid + 1
default:
hi = mid - 1
}
}
return -1
}
Time: O(log n) | Space: O(1)
Q35. Fibonacci with memoization. Easy
func fibMemo(n int, memo map[int]int) int {
if n <= 1 { return n }
if v, ok := memo[n]; ok { return v }
memo[n] = fibMemo(n-1, memo) + fibMemo(n-2, memo)
return memo[n]
}
cache := make(map[int]int)
fmt.Println(fibMemo(50, cache)) // 12586269025
Q36. Reverse a linked list. Medium
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
curr := head
for curr != nil {
next := curr.Next
curr.Next = prev
prev = curr
curr = next
}
return prev
}
Time: O(n) | Space: O(1)
Q37. Detect a cycle in a linked list. Medium
func hasCycle(head *ListNode) bool {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}
Floyd's cycle detection. Time: O(n) | Space: O(1)
Q38. Valid parentheses check. Easy
func isValid(s string) bool {
stack := make([]rune, 0)
pairs := map[rune]rune{')': '(', '}': '{', ']': '['}
for _, ch := range s {
if ch == '(' || ch == '{' || ch == '[' {
stack = append(stack, ch)
} else if open, ok := pairs[ch]; ok {
if len(stack) == 0 || stack[len(stack)-1] != open {
return false
}
stack = stack[:len(stack)-1]
}
}
return len(stack) == 0
}
fmt.Println(isValid("()[]{}")) // true
fmt.Println(isValid("([)]")) // false
Q39. BFS on a graph (adjacency list). Medium
func bfs(graph map[int][]int, start int) []int {
visited := make(map[int]bool)
queue := []int{start}
visited[start] = true
var order []int
for len(queue) > 0 {
node := queue[0]
queue = queue[1:]
order = append(order, node)
for _, neighbor := range graph[node] {
if !visited[neighbor] {
visited[neighbor] = true
queue = append(queue, neighbor)
}
}
}
return order
}
Q40. Longest common subsequence (DP). Hard
func lcs(a, b string) int {
m, n := len(a), len(b)
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
for i := 1; i <= m; i++ {
for j := 1; j <= n; j++ {
if a[i-1] == b[j-1] {
dp[i][j] = dp[i-1][j-1] + 1
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
}
}
}
return dp[m][n]
}
func max(a, b int) int {
if a > b { return a }
return b
}
fmt.Println(lcs("ABCBDAB", "BDCAB")) // 4
Time: O(mn) | Space: O(mn)
Mock Set: 5 Problems
Attempt each in 10-15 minutes:
- Write
mergeIntervals([][]int) [][]intthat merges overlapping intervals. - Implement a concurrent pipeline: generate integers -> square them -> filter even squares -> print.
- Given a matrix of 0s and 1s, count the number of islands using DFS.
- Write a function using channels to implement a pub/sub system with multiple subscribers.
- Implement
func topKFrequent(nums []int, k int) []intusing a min-heap.
Related reading: Go Interview Questions 2026 | Python Interview Questions 2026 | Node.js Interview Questions 2026 | AWS Interview Questions 2026
Methodology applied to this articlelast verified 8 Jun 2026
- No fabricated salary numbers or success rates. If we quote a range, it's sourced.
- No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
- No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
Explore this topic cluster
More resources in Interview Questions
Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.
Paid contributor programme
Sat this this year? Share your story, earn ₹500.
First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story - with byline.
Submit your story →Ready to practice?
Take a free timed mock test
Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.
Start Free Mock Test →More from PapersAdda
Google Coding Interview Rounds 2026: Loop + Rubric
How to Prepare for Google Coding Interview 2026: 12-Week Plan
Adobe Coding Round Questions 2026: Patterns + Solutions
Amazon Coding Round Questions 2026: Patterns + Solutions