skip to content

Core Language and Type System

Go is a small language whose interesting questions are about semantics: what a value copy actually copies, which method set satisfies an interface, and when the compiler demands a conversion.

part ofGo (Golang)overview, primer and where to startread it →
on this pageshow

explore

questions

189 · 8 sections

In Go, what happens when an int8 or a uint8 exceeds its maximum value?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Go integers wrap around silently: an int8 holding 127 becomes -128 when incremented, and a uint8 holding 0 becomes 255 when decremented. There is no panic and no promotion to a wider type. Only constant overflow is caught at compile time.

open as a page

What does iota do inside a Go const block, and what value does it start at?

level: juniorimportance: must knowfreq 78%
basics
~20 s

iota is a built-in counter usable only in const declarations: it is 0 on the first line of a const block and increases by one on each following line. Every new const block resets it to 0.

open as a page

In Go, what is the difference between type Celsius float64 and type Celsius = float64?

level: juniorimportance: must knowfreq 70%
basics
~20 s

type Celsius float64 declares a new, distinct type that shares float64's representation but has its own method set. type Celsius = float64 is an alias: Celsius and float64 are two names for one identical type.

open as a page

Why does `const r = 1.0 / 0.0` fail to compile in Go while a float64 variable divided by zero yields +Inf?

level: juniorimportance: must knowfreq 55%
basics
~20 s

The compiler evaluates constant expressions itself and rejects a constant division by zero outright. Float64 variables divide at run time under IEEE 754, so a nonzero value over zero gives positive or negative infinity, and zero over zero gives NaN.

open as a page

In Go, what do the expressions -7/2 and -7%2 evaluate to, and what rule fixes the sign of the remainder?

level: juniorimportance: must knowfreq 58%
basics
~10 s

Go truncates integer division toward zero, so -7/2 is -3, and the remainder takes the sign of the dividend, so -7%2 is -1. The identity x == (x/y)*y + x%y always holds.

open as a page

In Go, what is the difference between an array `[5]int` and a slice `[]int`?

level: juniorimportance: must knowfreq 88%
basics
~20 s

An array's length is part of its type, and assigning or passing one copies every element. A slice is a resizable view onto a backing array, carrying a length and a capacity; copying a slice shares that array.

open as a page

What does Go copy when you assign a struct that has slice and map fields?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Assignment copies a struct field by field. Number, string, bool and array fields become independent, but a slice, map or pointer field copies only the reference, so both structs still read and write the same underlying data.

open as a page

In Go, what is the difference between a keyed struct literal and a positional one?

level: juniorimportance: must knowfreq 68%
basics
~20 s

A keyed struct literal names each field and may omit fields, so order does not matter. A positional literal must supply every field in declaration order, so reordering fields silently changes what each value means.

open as a page

In Go, how do you distinguish a missing map key from one whose stored value is zero?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Use the two-value comma-ok form: v, ok := m[key]. ok is true only when the key is present. A one-value lookup returns the value type's zero value for a missing key, so 0, an empty string or false cannot tell you which happened.

open as a page

Go passes every argument by value — how do you write a function that modifies the caller's struct?

level: juniorimportance: must knowfreq 88%
basics
~20 s

Pass a pointer. A function parameter of type Player receives a copy, so writes to it die with the call. Declare the parameter as *Player, call it with &pl, and write p.HP = 40 — Go dereferences the selector for you.

open as a page

In Go, what does embedding a struct type as an anonymous field promote to the outer struct?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Writing a type inside a struct with no field name embeds it. The embedded type's fields and methods are promoted: you can use them directly on the outer value. The field itself is still named after its type.

open as a page

In Go, does embedding a struct make the outer type usable wherever the embedded type is expected?

level: juniorimportance: must knowfreq 70%
basics
~10 s

No. Embedding is composition, not subtyping: a struct that embeds StateRecord is its own distinct type and is never assignable to StateRecord. You pass the embedded value explicitly, as n.StateRecord.

open as a page

Why does a T value fail to satisfy a Go interface whose methods have pointer receivers?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Go's method set of T contains only methods declared with receiver T; methods declared with receiver *T belong to *T's method set alone. Interface satisfaction is checked against the method set, so only the pointer satisfies the interface.

open as a page

What is a method value in Go, and what does `f := runner.Warmup` capture?

level: juniorimportance: must knowfreq 62%
basics
~20 s

A method value is the function value you get by writing runner.Warmup with no call parentheses. Go evaluates and saves the receiver at that moment, so calling f() later runs Warmup on that saved receiver and takes no receiver argument.

open as a page

In Go, what is the difference between a value receiver and a pointer receiver on a method?

level: juniorimportance: must knowfreq 86%
basics
~20 s

A value receiver gets a copy of the value, so anything the method writes to it is discarded when the method returns. A pointer receiver gets the address of the caller's value, so its writes are visible afterwards.

open as a page

In a Go type assertion, how do `v := x.(T)` and `v, ok := x.(T)` differ?

level: juniorimportance: must knowfreq 80%
basics
~20 s

The one-result form v := x.(T) panics if the interface value x does not hold a T. The comma-ok form v, ok := x.(T) never panics: on a miss it yields T's zero value and sets ok to false.

open as a page

What does calling a method through a Go interface value cost compared with calling it on the concrete type?

level: juniorimportance: must knowfreq 55%
basics
~20 s

An interface method call is indirect: the target comes from the interface value's method table at run time, so the compiler cannot inline it or optimise across it. The lost inlining usually costs far more than the extra jump.

open as a page

What does Go's io.ReadWriteCloser gain by embedding io.Reader, io.Writer and io.Closer?

level: juniorimportance: must knowfreq 64%
basics
~20 s

Embedding folds the other interfaces' method sets into the new one, so io.ReadWriteCloser requires exactly Read, Write and Close and declares nothing extra. Any type with all three methods satisfies it automatically, with no declaration of intent.

open as a page

How does a Go type come to satisfy an interface like io.Writer with no implements keyword?

level: juniorimportance: must knowfreq 72%
basics
~20 s

A Go type satisfies an interface just by having every method the interface lists, with matching names and signatures. Nothing is declared anywhere: the compiler checks the match at the point where the value is assigned to the interface.

open as a page

What two parts does a Go interface value hold, and when is it equal to nil?

level: juniorimportance: must knowfreq 66%
basics
~20 s

A Go interface value holds two halves: a dynamic type and a value of that type. It is nil only when both halves are empty. An interface that has been given a type is non-nil even if the value stored is a nil pointer.

open as a page

In Go generics, what is a type constraint, and what can a function do with a value of a type parameter constrained by any?

level: juniorimportance: must knowfreq 72%
basics
~20 s

A constraint is an interface that bounds a type parameter, defining which types may be used as the type argument. The any constraint admits every type, so the body may only assign, pass and store such values, not compare or add them.

open as a page

When does Go infer a generic function's type arguments, and when must you write F[int] yourself?

level: juniorimportance: must knowfreq 68%
basics
~20 s

Go infers a generic function's type arguments from the ordinary arguments you pass at the call site. A type parameter that appears only in the result is not determined by any argument, so you must write it explicitly, as in Zeroint.

open as a page

Why does a Go function that returns `any` push work onto every caller, and how does a type parameter remove it?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Returning any gives the caller a value with no static type, so every call site must type-assert and can panic at run time. A type parameter returns the caller's own type instead, so the compiler checks the use.

open as a page

In Go, what does the `[T any]` in `func Reverse[T any](s []T)` declare, and where can T be used?

level: juniorimportance: must knowfreq 70%
basics
~20 s

The brackets declare a type parameter list. T is a placeholder for a type, constrained by any, so one Reverse serves every element type. T is in scope for the rest of the signature and the whole body.

open as a page

When do you constrain a Go type parameter with comparable rather than cmp.Ordered, and what does each permit?

level: middleimportance: must knowfreq 62%
basics
~20 s

Use comparable when the code needs equality: it is the predeclared constraint for types supporting == and !=, which is what a map key or set element requires. Use cmp.Ordered when the code needs ordering with <, >: integers, floats and strings.

open as a page

In Go, does a function literal capture an outer variable's value at creation, or the variable itself?

level: juniorimportance: must knowfreq 72%
basics
~20 s

A Go function literal captures the variable itself, not a snapshot of its value. Assignments made after the literal is created are visible when it runs, and assignments made inside it are visible to the enclosing code.

open as a page

In Go, what are the three non-range forms of for, and how do you write a while loop?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Go's for has three non-range forms: three-clause (init; condition; post), condition-only, and infinite (for with no clauses at all). The condition-only form is Go's while loop - the language has no while and no do-while keyword.

open as a page

What does Go's `defer` statement do, and when does the deferred call actually run?

level: juniorimportance: must knowfreq 85%
basics
~10 s

defer postpones a function call until the surrounding function finishes, not until the enclosing block ends. Several deferred calls run in reverse registration order, last registered first, and they run on every return path.

open as a page

In Go, how must a caller handle both results of a function returning `(int, bool)`?

level: juniorimportance: must knowfreq 78%
basics
~10 s

A Go call returning two values needs two targets: port, ok := parsePort(s). Write the blank identifier _ for any result you do not want. Binding one variable to it is a compile error.

open as a page

In a Go switch statement, what happens at the end of a case body, and what does `fallthrough` do?

level: juniorimportance: must knowfreq 70%
basics
~20 s

In Go a case body ends the switch automatically — there is no implicit fall-through and no break is needed. The fallthrough keyword, written as the last statement of a case, forces control into the next case's body.

open as a page

Why does the Go compiler reject a file that imports a package it never uses?

level: juniorimportance: must knowfreq 60%
basics
~20 s

Go makes an unused import a hard compile error rather than a warning: dead imports slow builds, grow the dependency graph and mislead readers. Delete the line, or make it deliberate with a blank import, an underscore before the path.

open as a page

What does a Go init() function do, and when does it run relative to main()?

level: juniorimportance: must knowfreq 72%
basics
~10 s

Go runs a package's init() functions automatically at startup: after that package's package-level variables are assigned and after every package it imports is fully initialized, but before main() begins. You cannot call init() yourself.

open as a page

What does putting a Go package under a directory named internal/ do, and who can still import it?

level: juniorimportance: must knowfreq 62%
basics
~20 s

A package whose import path contains an internal element can be imported only by code inside the tree rooted at that internal/ directory's parent. Any other import fails at build time with 'use of internal package ... not allowed'.

open as a page

In Go, what does `:=` inside an if block do when the enclosing function already declares that name?

level: juniorimportance: must knowfreq 62%
basics
~20 s

It declares a new variable that lives only until that block's closing brace. The outer variable of the same name is hidden, not assigned, so whatever the inner block writes is lost when the block ends.

open as a page

In Go, what makes an identifier visible to code in another package?

level: juniorimportance: must knowfreq 82%
basics
~20 s

The case of its first letter. A name beginning with an upper-case letter is exported and can be used by importing packages; a name beginning with a lower-case letter is usable only inside the package that declares it.

open as a page

Given `type UserID string`, why does `var id UserID = "u-1"` compile but `var s string = id` not?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An untyped string constant is assignable to any type whose underlying type is string, so the literal works. But UserID and string are two distinct named types, so moving a value between them needs an explicit conversion: string(id).

open as a page

Which Go types can be compared with `==`, and which ones fail to compile?

level: juniorimportance: must knowfreq 74%
basics
~20 s

Booleans, numbers, strings, pointers, channels, interfaces, and structs or arrays built entirely from comparable parts support ==. Slices, maps and functions do not: the compiler rejects ==, and the only equality they allow is a comparison against nil.

open as a page

In Go, which kinds of type can hold nil, and does nil mean the same thing for each?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Six kinds of type can be nil: pointers, slices, maps, channels, functions and interfaces. nil is the zero value of each, not one shared value, so every kind has its own representation and its own rules about what you may safely do.

open as a page

Why can a `chan int` be assigned to a `<-chan int` variable, but never the reverse?

level: middleimportance: should knowfreq 45%
basics
~20 s

A bidirectional channel may be assigned to a receive-only or send-only variable, because that only removes capability. The reverse would invent capability the value never had, so it is neither assignable nor convertible. Direction is part of the static type.

open as a page

What must be true for two Go interface values to be equal with `==`?

level: middleimportance: should knowfreq 46%
basics
~20 s

Two interface values are equal only when both hold nothing at all, or when their dynamic types are identical and their dynamic values are equal. An any holding int(1) never equals an any holding int64(1).

open as a page