Checkpoint: Standard Library

This checkpoint consolidates the standard-library section — iota, strings, runes, fmt, conversions, embedding, slices, maps, sorting, time, and regexp — into one build challenge plus a quiz that proves you can combine them.

Learn Checkpoint: Standard Library in our free Go course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free Go course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Practice in This Checkpoint

📚 Section Recap

A quick map of everything this section covered — skim it, and revisit any lesson where a row feels shaky.

🛠️ Build Challenge: Score Leaderboard

Turn a block of messy name,score text into a ranked leaderboard. This is a complete mini-pipeline: parse with strings + strconv , aggregate the best score per name into a map, sort deterministically (score descending, then name), and report an aligned table with fmt .

A complete, compiling solution. Each numbered comment maps to a recap topic — note how TrimSpace rescues the ben, 75 line and the map keeps only each name's best score.

⏱ Timed Quiz

📝 Checkpoint Quiz

Answer each before you reveal it. If you miss one, the recap row above links straight back to the lesson.

6 . len counts bytes , and the é is 2 bytes in UTF-8, so a 5-character string is 6 bytes. Use utf8.RuneCountInString for the character count (5).

A sub-slice shares the parent's backing array and inherits its capacity. If append stays within that capacity it writes in place , overwriting later parent elements. Use copy or the full-slice expression s[low:high:max] to avoid it.

Use the comma-ok form: v, ok := m[k] . ok is true only when the key exists; a plain lookup returns the zero value for both "absent" and "present with value 0".

sort.SliceStable (and slices.SortStableFunc ). Plain sort.Slice is not guaranteed stable, so ties can be reordered.

"2006-01-02" . Go uses the reference date Mon Jan 2 15:04:05 MST 2006 ; you spell the output with that exact date's pieces, not letter codes like YYYY .

Compiling is relatively expensive and the pattern is usually constant. Doing it once at startup (a package-level var ) avoids recompiling in hot loops, and an invalid pattern panics immediately rather than mid-request. The compiled *Regexp is safe for concurrent use.

Once your leaderboard works, extend it: after the table, print the average of the best scores formatted to one decimal (e.g. avg: 88.3 ) using %.1f . Sum the best values and divide by len(best) as a float64 .

This reuses conversions ( float64(...) ), maps, and fmt precision — the whole section in one extra line.

Practice quiz

What does len("héllo") return in Go, and why?

  • 5, because there are 5 characters
  • 5, because Go counts runes
  • 6, because len counts bytes and é is 2 bytes in UTF-8
  • 7, including a null terminator

Answer: 6, because len counts bytes and é is 2 bytes in UTF-8. len counts bytes; é is 2 bytes in UTF-8, so a 5-character string is 6 bytes. Use utf8.RuneCountInString for 5.

Why does the leaderboard call strings.TrimSpace on each field before strconv.Atoi?

  • Because input like " 75" has stray whitespace that Atoi would reject
  • To convert the field to uppercase
  • Because Atoi only accepts trimmed strings of length 2
  • To remove commas from the number

Answer: Because input like " 75" has stray whitespace that Atoi would reject. strconv.Atoi rejects leading/trailing spaces, so TrimSpace makes parsing robust against messy input like 'ben, 75'.

How do you tell a missing map key apart from a key stored with a zero value?

  • Compare the value to nil

The comma-ok form returns ok=true only when the key exists; a plain lookup gives the zero value for both cases.

In the build challenge, why are the names collected into a slice and sorted before printing?

  • Because maps cannot be ranged over
  • Because map iteration order is randomized, so sorting makes the output deterministic
  • To remove duplicate names
  • Because fmt.Printf needs a slice

Answer: Because map iteration order is randomized, so sorting makes the output deterministic. Go randomizes map iteration order; collecting keys into a slice and sorting them produces stable, testable output.

Which sort function keeps equal elements in their original relative order?

  • sort.SliceStable
  • sort.Slice
  • sort.Ints
  • sort.Reverse

Answer: sort.SliceStable. sort.SliceStable (and slices.SortStableFunc) is stable; plain sort.Slice may reorder ties.

What layout string formats a time as 2026-06-18 with time.Format?

  • "YYYY-MM-DD"
  • "01-02-2006"
  • "2006-01-02"
  • "2021-12-31"

Answer: "2006-01-02". Go uses the reference date Mon Jan 2 15:04:05 MST 2006, so the layout is the literal "2006-01-02".

What is the difference between a byte and a rune in Go?

  • byte is int32 and rune is uint8
  • byte is an alias for uint8; rune is an alias for int32 (a Unicode code point)
  • They are identical aliases
  • byte is for ASCII only; rune cannot hold ASCII

Answer: byte is an alias for uint8; rune is an alias for int32 (a Unicode code point). byte = uint8 (a raw byte), rune = int32 (a Unicode code point); ranging a string yields runes.

Why compile a regular expression with regexp.MustCompile at package level rather than inside a hot loop?

  • MustCompile is the only way to compile a regex
  • Package-level regexes match faster than local ones
  • It makes the regex case-insensitive
  • Compiling is relatively expensive, so doing it once avoids recompiling, and an invalid pattern panics immediately at startup

Answer: Compiling is relatively expensive, so doing it once avoids recompiling, and an invalid pattern panics immediately at startup. Compile once at startup: it avoids repeated cost in hot paths, fails fast on a bad pattern, and the *Regexp is safe for concurrent use.

Why might appending to a sub-slice unexpectedly change the parent slice?

  • append always copies, so it never affects the parent
  • A sub-slice shares the parent's backing array, and append within capacity writes in place
  • Sub-slices are pointers to the parent variable
  • Because Go re-sorts slices after append

Answer: A sub-slice shares the parent's backing array, and append within capacity writes in place. If append stays within the shared backing array's capacity it overwrites parent elements; use copy or s[low:high:max] to avoid it.

What does the format verb %-6s do in fmt.Printf?

  • Prints the string right-aligned in 6 columns
  • Truncates the string to 6 characters
  • Prints the string left-aligned, padded to a minimum width of 6
  • Prints 6 copies of the string

Answer: Prints the string left-aligned, padded to a minimum width of 6. The minus flag left-justifies and 6 sets a minimum field width, padding shorter strings with spaces to align columns.