When would you use Rune Vs Byte in a real project
Fast recall
Quick revision
Core answer
Practical understanding of Rune Vs Byte.
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 default is runes, with byte-offset indices — the surprising part:
s := "héllo"
for i, r := range s {
fmt.Println(i, r) // 0 104 | 1 233 | 3 108 | 4 108 | 5 111
}Executed: i starts 0 (h), then 1 (é — rune 233 at byte offset 1), then JUMPS to 3 (l — é was 2 bytes wide). Index = byte offset; value = decoded rune. range walks UTF-8, not bytes.
Why byte offsets: slicing composes — s[i:] needs byte offsets, and range's i is exactly where each rune starts. Building substrings from iteration output is direct.
Explicit byte iteration, when you want the raw encoding:
for i := 0; i < len(s); i++ {
b := s[i] // 104, 195, 169, 108...
}No offset jumps here — i advances by 1 — but values at multi-byte positions are encoding fragments, not characters.
The reversed mistake: []rune(s) in a loop (O(n) allocation per conversion) when range decodes for free. Convert only for random rune access or mutation.
When would you use Rune Vs Byte in a real project
Direct Answer
range iterates RUNES (value is a code point, index is a BYTE OFFSET). Indexing s[i] gives BYTES. For byte iteration: classic loop over len(s), or range []byte(s).
Deep Dive & Architecture
The decoder behind range: each iteration reads the current byte, infers width from leading bits (UTF-8 is self-synchronizing forward), gathers that many bytes, decodes, returns (offset, rune). O(n) total, O(1) per rune, no allocation — decoding happens in registers.
Why byte-offset (not rune-index) for the loop's first value: s[start:end] needs byte offsets, and range's i gives exactly where each rune starts — substring building from iteration is direct. A rune-index loop can't slice without recomputing offsets.
The invalid-UTF-8 case: a Go string CAN hold arbitrary bytes (strings are byte sequences, not guaranteed UTF-8). range handles invalid sequences by yielding U+FFFD (replacement character) with width 1 — no panic, no stop; each invalid byte becomes one replacement rune. That makes range safe over ANY string — and explains why byte loops and rune loops can disagree on corrupt input's count.
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 Rune Vs Byte, and when would you use it?
- What is a common mistake when using Rune Vs Byte?
- How would you compare Rune Vs Byte with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.