Go Quiz

Do you know Go?

February 5, 2024

  1. T/F? In Go, semicolons are required to terminate statements.
    Answer True, but it's usually the compiler that inserts them on behalf of the programmer. Go Spec: Semicolons
  2. T/F? You can define lexically scoped blocks anywhere in a function.
    Answer

    True: Go Spec: Blocks (which means you can do stuff like this.

  3. T/F? A deferred function's arguments are not evaluated until the deferred statement is executed.
    Answer

    False: The Go Blog: Defer, Panic, and Recover

    A deferred function's arguments are evaluated when the defer statement is evaluated.
  4. T/F? In a panicking goroutine recover() will return what panic() received & resume execution.
    Answer

    True: The Go Blog: Defer, Panic, and Recover

    Recover is a built-in function that regains control of a panicking goroutine...During normal execution, a call to recover will return nil and have no other effect. If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution.
  5. T/F? The recover function is only useful inside deferred functions.
    Answer

    True: The Go Blog: Defer, Panic, and Recover

    Recover is only useful inside deferred functions.
  6. T/F? Deferred function calls are executed in First-In-First-Out order.
    Answer

    False: The Go Blog: Defer, Panic, and Recover

    Deferred function calls are executed in Last In First Out order after the surrounding function returns.
  7. T/F? Deferred functions may read but not assign to the returning function's named return values.
    Answer

    False: The Go Blog: Defer, Panic, and Recover

    Deferred functions may read and assign to the returning function’s named return values.
  8. T/F? Excluding cases such as panics, a go program exits when all goroutines have finished.
    Answer

    False: The Go Spec: Program Execution

    Program execution begins by initializing the program and then invoking the function main in package main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
  9. T/F? Naked returns (like naked mole rats) are visually unappealing, best left out of sight.
    Answer

    TRUE

  10. Given type Point struct { X, Y int } why would this code make any self-respecting gopher cringe? p := Point{1, 2}
    Answer

    The assignment statement utilizes a composite literal (see the Go Spec: Composite Literals. When a struct type is initialized using a composite literal:

    An element list that does not contain any keys must list an element for each struct field in the order in which the fields are declared.

    The above is a very rigid requirement. Always specifying keys (field names) in struct literals is a much more flexible way to code and allows for the addition and re-ordering of fields without breaking any calling code.

  11. Complete the following two Go Proverbs: 'Clear is better than ______. __________ is never clear.'
    Answer

    Clear is better than clever. Reflection is never clear.

  12. Jeopardy Clue: "The utility whose style is no one's favorite, but is still everyone's favorite."
    Answer

    What is go fmt? (see the Go Proverbs)

  13. What is the difference between concurrency and parallelism, and why does it matter?
    Answer

    Concurrent execution refers to the capability of the runtime to multi-task when presented with, for instance, blocking I/O. Parallelism refers to executing multiple tasks at the same time (using multiple processors/threads). A concurrent program written in Go can be executed in parallel simply by ensuring that GOMAXPROCS is greater than 1 (the default value since Go 1.5 has been the number of cores available).

  14. The strings.NewReplacer() function panics if an odd number of arguments are passed. Is this a good approach?
    Answer

    It certainly seems odd for a standard library function such as this to panic if passed an odd number of arguments. Perhaps it would be better to have defined the function with an error return value:

    def NewReplacer(args ...string) (*Replacer, error) {...}

    Because of the Go 1.0 compatibility promise, the signature for this function won't be changing anytime soon, but we could create a custom 'builder' to smooth this out, something with a Register(search, replace string) method.

  15. What fmt 'verb' produces the same output as fmt.Sprintf("%s", reflect.TypeOf(a)) but without any call to reflect.TypeOf()?
    Answer

    fmt.Sprintf("%T", a)

  16. T/F? Spaces are always added between operands passed to fmt.Println().
    Answer

    True

  17. T/F? Spaces are always added between operands passed to fmt.Print().
    Answer

    False (only when neither is a string)

  18. Simplify by removing a redundant element: csv.NewReader(bufio.NewReader(file))
    Answer

    Since the csv.NewReader function wraps the provided reader in bufio.NewReader for the caller, it's sufficient to simply use csv.NewReader(file).

  19. Simplify by replacing with another 'strings' function: strings.Split(s, "\t\n\v\f\r ")
    Answer

    strings.Fields(s)

  20. Simplify by replacing with another 'strings' function: strings.Replace(s, "a", "b", -1)
    Answer

    strings.ReplaceAll(s, "a", "b")

  21. T/F? a := new(Thing) is equivalent to a := Thing{}
    Answer

    False! The new function returns a pointer.

  22. T/F? var a any = new(Thing) is equivalent to var a any = reflect.New(reflect.TypeOf(Thing{})).Interface()
    Answer

    True! The reflect.New function is analogous to the built-in new function. They both return pointers to a newly allocated zero-value of the provided type.

  23. T/F? t1 := T{}; t2 := reflect.ValueOf(t1).Interface(); fmt.Print(t1 == t2)
    Answer

    True! See "The Laws of Reflection".

-Michael Whatcott