Theory

Bytes vs characters — len("ąžuolas") = 9

Gotcha

How many characters are in the word "ąžuolas" (Lithuanian for oak)? Seven. And what does len return?

len("ąžuolas")  // 9  — NOT 7!

Because len counts bytes, not characters. A computer stores text as UTF-8: plain ASCII letters (a, z, u) take 1 byte, but Lithuanian letters with diacritics (ą, ž, č, š, ę, ė, į, ų, ū) take 2 bytes. The word "ąžuolas" has two of them (ą and ž), so 7 characters = 7 + 2 extra bytes = 9 bytes.

You get the real character count two ways:

utf8.RuneCountInString("ąžuolas")  // 7  — import "unicode/utf8"
len([]rune("ąžuolas"))             // 7  — []rune turns it into a list of characters

A rune in Go is one character (a Unicode code point). []rune(s) splits a string into characters — then indexing and counting are correct. s[0] would return the first byte (possibly half a letter!), while []rune(s)[0] returns the first character.

When does it matter? When you check text length (a title up to 60 characters), when you truncate text (so you don't cut "ą" in half), or take a "first letter". English text happens to count right with len — because ASCII letters are 1 byte each. But Lithuanian text would almost always be wrong.

strings.Builder — for joining in a loop. When you "grow" a string in a loop with +=, Go creates a new string each time (the old one is immutable), so N times is slow (O(n²)). strings.Builder accumulates into one buffer:

var b strings.Builder
for i := 0; i < n; i++ {
    b.WriteString("= ")
}
result := b.String()

For one record you won't notice, but in lesson 8, with many records to join into one report, Builder will be the right choice.

Tip. Don't fear the diacritics — Go handles Unicode well; you just have to tell bytes apart from characters. The rule is simple: showing text to a user or checking length — think in characters ([]rune, utf8.RuneCountInString). Reading a file or the network — there it's natural to think in bytes.