Reverse A Slice
Fast recall
Quick revision
Core answer
Practical understanding of Slice Tricks.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
The canonical loop:
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}Two indexes — one from each end — swap, walk toward the middle, stop when they cross. In place (no new slice), O(n) time, O(1) space, and len/2 swaps total.
Things worth knowing around it:
The condition is i < j, not i <= j — the middle element (odd lengths) doesn't need to swap with itself.
It mutates the input — when the caller needs the original too, copy first (previous trick), then reverse the copy.
There's no standard-library Reverse (a deliberate omission; the loop is 3 lines and adding it would invite the same for dozens of other micro-operations). Go 1.21+'s slices package has a Reverse — worth mentioning as the modern one-call answer:
import "slices"
slices.Reverse(s) // same two-pointer, library-maintainedReverse A Slice
Direct Answer
Two-pointer swap: walk inward from both ends, swapping — in place, no allocation.
Deep Dive & Architecture
The loop is two-pointer invariants: i only rises, j only falls, they swap every step, and the loop ends at the crossing. Each swap places one element in its final position — after the loop, every element has been placed, which is why it's O(n) with n/2 swaps and no allocation.
The mechanics worth noticing: Go's multiple assignment, s[i], s[j] = s[j], s[i], evaluates both right-hand sides before assigning either — the classic swap without a temp. That single language feature is why the reversal is three lines total.
slices.Reverse (Go 1.21+) is the same algorithm, standardized — the generic version over any element type. The standard library resisted a Reverse for a decade because three lines didn't justify an API; generics changed the calculus: one maintained implementation beats a million re-writes, and the package's tests catch the boundary cases hand-written loops sometimes miss (the i <= j off-by-one that swaps the middle with itself, the len 0/1 edge).
String reversal is a different question — and a classic trap: reversing a string by bytes (b[i], b[j] swap) destroys multi-byte UTF-8 runes. Reverse the RUNES ([]rune(s), swap, string(...)) and the result stays valid — at the cost of the rune-slice allocation. That byte-index vs rune-index boundary on strings is a topic of its own for good reason.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Slice Tricks, and when would you use it?
- When would you use Slice Tricks in a real project?
- What is a common mistake when using Slice Tricks?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.