Go Guide

Playground

Visualizers

Every interactive figure from the lessons. Change the input, press Run, then step with the buttons or the ← → keys. Each step explains what the algorithm decided and why.

Go internals

InteractiveHow append grows a sliceA slice is a window (pointer, len, cap) onto a backing array. When len reaches cap, append allocates a bigger array and copies.
len 0cap 0arrays allocated 0
array
(no array yet)

var s []int: a nil slice. No array is allocated until the first append.

1 / 12
InteractiveSlices sharing a backing arrayb := a[1:3] does not copy. Writes through b show up in a, and append on b can overwrite a's elements while there is spare capacity.
a [5 elems]b len 0b cap 5
a's array
01
12
23
34
45

a := []int{1, 2, 3, 4, 5}: len 5, cap 5.

1 / 8
InteractiveValues vs pointersGo passes everything by value: a function gets a copy. Passing a pointer copies the address, so the function can change the original.
variableaddressvalue
main: x0xc00001010

x := 10. x lives at some address, shown here as 0xc000010.

1 / 7
Interactivedefer runs last-in, first-outEach defer pushes a call onto the function's defer stack. When the function returns (or panics), the calls run in reverse order.
defer stack
empty
ran
–

The function starts. Nothing is deferred yet.

1 / 9
InteractiveChannels: unbuffered vs bufferedA send blocks until there is room: on an unbuffered channel that means a receiver is ready; on a buffered one, a free slot.
sender readyreceiver busy elsewhere
chan (cap 2)
·
·
received
–

ch := make(chan int, 2). The producer goroutine will send 4 values; main receives with for v := range ch.

1 / 13

Arrays & strings

InteractiveTwo pointers: pair with a target sumOn a sorted slice, move the left pointer to grow the sum and the right pointer to shrink it.
l 0r 5sum 12target 10
01l
13
24
36
48
511r

Start at both ends. Each step discards one element that cannot be part of the answer.

1 / 6
InteractiveSliding window: max sum of k in a rowSlide a window of size k: add the element entering on the right, subtract the one leaving on the left.
window [0, 2]sum 8best 8
02left
11
25right
31
43
52
66
71

First window: 2 + 1 + 5 = 8.

1 / 7
InteractiveSliding window: longest substring without repeatsGrow the window on the right; when a character repeats, jump the left edge past its previous copy.
left 0right 0best 1
0aleft/right
1b
2c
3a
4b
5c
6b
7b

'a' is new to the window. Window "a" has length 1.

1 / 9
InteractivePrefix sums and a range queryBuild pre[i] = sum of the first i elements once; then any range sum is one subtraction.
nums
03
11
24
31
45
59
pre
0

pre[0] = 0: the sum of no elements.

1 / 8
InteractiveKadane's algorithm: maximum subarrayAt each element, either extend the best subarray ending just before it, or start fresh.
cur -2best -2
0-2start/i
11
2-3
34
4-1
52
61
7-5
84

cur = best = -2: the best subarray ending at index 0 is just [-2].

1 / 12
InteractiveTrapping rain water (two pointers)Water above a bar is limited by the lower of the tallest bars to its left and right. Move inward from the side with the lower max.
leftMax 0rightMax 0water 0

h[l]=0 < h[r]=1: the right side has a wall at least as tall, so the left max (0) decides. Water at 0: 0 - 0 = 0.

1 / 12
InteractiveKMP string searchOn a mismatch, the failure table says how much of the pattern still matches, so the text pointer never moves back.
pattern
0a
1b
2a
3b
4c
lps
0
0

Building the table: "ab" has no prefix that is also a suffix. lps[1] = 0.

1 / 18

Stacks, queues & hashing

InteractiveMonotonic stack: days until warmerThe stack holds days still waiting for a warmer one; a warm day resolves every colder day on top.
i 0
temp
073
174
275
371
469
572
676
773
stack
0:73
answer

73 is not warmer than the top of the stack. Push day 0; it waits.

1 / 9
InteractiveMonotonic deque: sliding window maximumThe deque keeps indexes whose values decrease front to back, so the front is always the window's max.
nums
01
13
2-1
3-3
45
53
66
77
deque
0:1
maxes
–

Push 0. The first window is not full yet.

1 / 8
InteractiveHash table with linear probinghash(key) picks a slot; if it is taken, try the next slot. Clusters of full slots make probes longer.
slots
0
1
2
3
4
5
6
7
8
9

10 empty slots. hash(k) = k mod 10.

1 / 9
InteractiveLRU cacheA map finds entries in O(1); a doubly linked list keeps them in recency order so the least recently used is always at the back.
hits 0misses 0
MRU → LRU
empty
map keys
empty

Empty cache with room for 3.

1 / 11

Sorting

InteractiveBubble sortRepeatedly swap neighbors that are out of order; each pass bubbles the largest remaining value to the end.

5 > 2: swap them.

1 / 30
InteractiveSelection sortFind the smallest remaining value and swap it into the next position.

Scanning for the smallest from index 0: smallest so far is 5, looking at 2.

1 / 36
InteractiveInsertion sortGrow a sorted prefix: take the next value and shift bigger ones right until it fits.

Take 2. Everything left of index 1 is already sorted.

1 / 28
InteractiveMerge sortSort each half recursively, then merge the two sorted halves by repeatedly taking the smaller front value.

Merge [5] and [2], both already sorted.

1 / 32
InteractiveQuicksort (Lomuto partition)Pick the last element as pivot, move smaller values to its left, then sort each side.

Partition indexes 0..7 around pivot 4.

1 / 29

Trees & heaps

InteractiveBinary search tree: insert and searchEach comparison sends a value left (smaller) or right (larger). Try a sorted input to see the tree degenerate.
8

Insert 8 as the root.

1 / 12
InteractiveMin-heap: push and popPush appends and sifts up; pop moves the last element to the root and sifts down. The tree is stored in a plain slice.
5
slice
05

Push 5: append it at index 0, the next free spot on the bottom level.

1 / 26
InteractiveMedian of a data stream (two heaps)A max-heap holds the smaller half and a min-heap the larger half. Keep them balanced and the median sits on top.
median 5seen 1
stream
5
15
1
3
8
7
9
10
20
low (max-heap)
5
high (min-heap)
empty

Add 5 to low (it is ≤ low's max). Median = top of low = 5.

1 / 9
InteractiveSegment tree: range sum queryEach node stores the sum of a range. A query uses nodes fully inside the range and skips nodes fully outside.
[0,7]39[0,3]22[4,7]17[0,1]13[2,3]9[4,5]9[6,7]8[0,0]5[1,1]8[2,2]6[3,3]3[4,4]2[5,5]7[6,6]2[7,7]6
nums
05
18
26
33
42
57
62
76

Built bottom-up: each leaf is one element, each parent is the sum of its two children. Now query sum(2..6).

1 / 11

Graphs

InteractiveBFS on a grid: shortest pathBFS explores in rings of equal distance, so the first time it reaches E is along a shortest path. Edit the maze: # is a wall.
queue 1
S
E

Start with S in the queue at distance 0. Numbers show the distance from S; outlined cells are waiting in the queue.

1 / 27
InteractiveTopological sort (Kahn's algorithm)Repeatedly take a node with no remaining prerequisites. If some nodes are never freed, there is a cycle.
queue
go
lint
order
–
builddeploygolinttest
in-degree12002

Count incoming edges. Nodes with in-degree 0 (go, lint) have no prerequisites and start in the queue.

1 / 7
InteractiveDijkstra's shortest pathsAlways expand the closest unfinished node, and relax its edges. Stale heap entries are skipped.
heap
(A,0)
ABCDE
dist0∞∞∞∞
via–––––

dist[A] = 0, everything else ∞. The heap holds (A, 0).

1 / 10
InteractiveUnion-Find with union by sizeEach group is a tree; Find walks to the root. Union attaches the smaller tree under the larger root.
parent
00
11
22
33
44
55
66
77
size
1
1
1
1
1
1
1
1
groups
{0}
{1}
{2}
{3}
{4}
{5}
{6}
{7}

Every item starts as its own root: parent[i] = i.

1 / 8
InteractiveKruskal's minimum spanning treeTake edges from cheapest to most expensive, skipping any edge whose ends are already connected.
total 0edges taken 0 / 4
A-CB-CD-EA-BB-DC-DC-E
weight1234589

Sort all edges by weight. Every node starts in its own group.

1 / 7

Dynamic programming & math

InteractiveCoin change (fewest coins)dp[a] = fewest coins that make amount a. Each cell tries every coin as the last one used.
dp
00
1∞
2∞
3∞
4∞
5∞
6∞

dp[0] = 0: zero coins make amount 0. Every other amount starts as ∞ (impossible so far).

1 / 8
InteractiveLongest common subsequencedp[i][j] is the LCS of the first i letters of A and the first j of B. A match goes diagonal + 1; otherwise take the better of up and left.
∅bdcaba
∅0000000
a0
b0
c0
b0
d0
a0
b0

Row 0 and column 0 are empty prefixes: their LCS is 0.

1 / 44
InteractiveLongest increasing subsequence (patience sorting)tails[k] is the smallest possible last value of an increasing subsequence of length k+1. Binary search where each number goes.
nums
010
19
22
35
43
57
6101
718
84
919
tails
010

10 is bigger than every tail: it extends the longest subsequence. Length is now 1.

1 / 11
InteractiveSieve of EratosthenesFor each prime p, cross out its multiples starting at p². Whatever survives is prime.
0123456789
10111213141516171819
20212223242526272829
30313233343536373839
40414243444546474849
50515253545556575859
60

0 and 1 are not prime. Start with 2.

1 / 6

System design

InteractiveToken bucket rate limiterThe bucket refills at a steady rate up to its capacity. Each request spends one token; with no tokens, it is rejected (HTTP 429).
tokens 3
requests
0s
0s
0s
0s
0.5s
1s
1.2s
2.5s
2.6s
2.7s
6s

The bucket starts full with 3 tokens, refilling 1/s.

1 / 13
InteractiveConsistent hashingServers and keys are hashed onto a ring; each key belongs to the first server clockwise. Removing a server only moves that server's keys.
0°cache-acache-bcache-ccache-d

Each server is hashed to a point on a 360° ring.

1 / 4
InteractiveSnowflake IDsA 64-bit ID packs a timestamp, a machine number and a per-millisecond counter, so every machine can create unique, time-ordered IDs without coordination.
signtimestamp (41 bits)machine (10)sequence (12)
0000000000000001110101101111001101000101010000100101000000000101
1 bit123456789 ms375

The top bit stays 0 so the ID is positive in a signed int64.

1 / 5
InteractiveBase62 short codesA URL shortener turns a numeric ID into a short code by repeatedly dividing by 62 and mapping each remainder to 0-9, a-z, A-Z.
n 125000000n % 62 2
code
2

125000000 = 2016129 × 62 + 2. Remainder 2 is '2'. Prepend it; continue with 2016129.

1 / 6