Go Interview Questions
Why Go?
- a simple language with elegant and easy to understand syntax structures.
- fast to build and execute.
- uses a compile-link model for generating executable binaries from the source code.
- supports concurrency at the language level. Golang is optimized for concurrency and works well at scale.
- automatic garbage collection; more efficient than Java or Python because it executes concurrently alongside the program.
- more readable than other languages due to a single standard code format.
- good standard library.
- static type checking.
- good support for writing unit test.
What are packages in Go?
Packages are directories within your Go workspace that contain Go source files or other packages.
- Every function, variable, and type from your source files are stored in the linked package.
- Every Go source file belongs to a package, which is declared at the top of the file using:
package <packagename>
. - Packages can be imported by
import <packagename>
.
What are differences between packages and modules in Go?
- a package is a directory of
.go
files. - a module is a collection of Go packages, with dependencies and versioning built-in.
- a module has a file
go.mod
at its root, it defines the module's import path and its specific dependencies.
- a module has a file
With modules:
- Go projects do not need to reside in
GOPATH
. - Package management is greatly improved.
How to do type conversion in Go?
To convert a number to int
: int(a)
.
How to print type of variable in Go?
Use %T
in fmt.Printf()
.
fmt.Printf("Type: %T\n", a)
How to export an identifier in Go?
- If the identifier starts with a capital letter, it is exported from the package, and can be accessed by anyone outside the package that declares it.
- If the identifier starts with a lowercase letter, it can only be accessed from within the package.
What is a pointer in Go?
A pointer is used to hold the address of a variable.
Which common language features are NOT supported by Go?
Golang doesn't provide support for the following features:
class
keyword.- type inheritance.
- operator overloading.
- method overloading.
- pointer arithmetic.
- try / catch for error handling.
- generics (only supported after 1.18).
How to define interfaces
Interfaces are a special type
in Go that define a set of method signatures but do not provide implementations.
type geometry interface {
area() float64
perim() float64
}
What is the empty interface in Go?
Empty interface: an interface
type that specifies zero methods.
interface{}
Used to handel values of unknown type.
func foo(v interface{}) {
// v can be any type.
}
How to handle errors in Go?
Can have multiple checks within the same block, to limit err
scope:
if err := Foo(); err != nil {
// ...
}
Bubble up the errors:
func Bar() error {
f, err := Foo()
if err != nil {
return fmt.Errorf("got error: %w", err)
}
}
How to concatenate strings?
Use +
.
What are function closures?
Function closures: a function value that references variables from outside its body.
What are Lvalue and Rvalue in Golang?
Lvalue
- Refers to a memory location.
- Represents a variable identifier.
- Mutable.
- May appear on the left or right side of the
=
operator.
Rvalue
- Represents a data value stored in memory.
- Represents a constant value.
- Always appears on the
=
operator's right side.
Can you return multiple values from a function?
Yes. For example:
func foo() (string, string) {
return "a", "b"
}
Swap the values of two variables without a temporary variable
b, a = a, b
What is the easiest way to check if a slice is empty?
len(slice) == 0
String Literals
- Raw string literals:
`raw string`
- Interpreted string literals:
"raw string"
What are the scopes of variables in Go?
In Go, every variable is statically scoped, meaning a variable scope can be identified at compile time. There are two scopes in Go:
- Local variables: declared inside a function or a block and is accessible only within these entities.
- Global variables: declared outside function or block and is accessible by the whole source file.
What is slice in Go?
Slice
: variable length sequence for homogeneous data.
An array
has a fixed size. A slice
, on the other hand, is a dynamically-sized, flexible view into the elements of an array
.
Does Go support generics?
Yes, since Go 1.18.
What's the difference between new
and make
?
new
: allocates "zeroed" storage for a new item of typeT
and returns its address, a value of type*T
.make
: used to initialize slices, maps, and channels; it does not return a pointer.
p := new(chan int) // p has type: *chan int
c := make(chan int) // c has type: chan int
What is Type Assertion in Go?
t, isSuccess := i.(T)
It asserts that the interface value i
has the concrete type T
and assigns the value to the variable t
. If the interface value i
has T
, then t
will be assigned; otherwise isSuccess
is false and t
would have the zero value.
What's the difference between :=
and =
?
:=
(short variable declaration): for declaration + assignment.=
: for assignment only.
var foo int = 10
is the same as foo := 10
.
Note:
- Go won't let you use
:=
to assign to a variable that has already been declared, unless you are assigning to multiple variables at once, and at least one of those variables is new. :=
cannot be used outside a function.
What are byte
and rune
in Go?
byte
: alias foruint8
. Represents ASCII chacaters.rune
: alias forint32
. Represents a single Unicode character.
How to test code in Go?
- Go has built-in support for unit testing.
- Since Go 1.18, fuzzing (a type of vulnerability testing that throws arbitrary data at a piece of software to expose unknown errors and is emerging as a common testing scheme in enterprise development) is integrated into Go's standard toolchain.
How is Go different from other programming languages?
- Go's
switch
cases need not be constants, and the values involved need not be integers. - Unlike C, Go has no pointer arithmetic.
- Go does not have reference variables.
- It is not possible to create a Go program where two variables share the same storage location in memory.
- Interfaces are implemented implicitly. Go interfaces are statically typed duck typing, Java interfaces are alternative to multiple inheritance.
How does inheritance work in Go?
There's no inheritance (e.g. extends
and override
) in Go, composition is preferred over inheritance; type embedding is the way to implement composition.
How to clean up dependencies?
$ go mod tidy
Go Memory Model?
Go 1.19 introduces a revised memory model and new types that make it easier to use atomic values. With Go 1.19, the language's memory model has been revised to align Go with the memory model used by C, C++, Java, JavaScript, and Swift. https://tip.golang.org/doc/go1.19
What are Go's env variables?
To get env:
$ go env
GOROOT
: specifies where your GO SDK is located.GOPATH
: specifies the root of your workspace (where your packages and dependencies are located).
Vendor
The vendor
folder is auto created by go mod vendor
:
- Dependencies in
go.mod
will be downloaded invendor
folder. go mod vendor
also creates the filevendor/modules.txt
that contains a list of vendored packages and the module versions they were copied from.- When vendoring is enabled, this manifest is used as a source of module version information, as reported by
go list -m
andgo version -m
.
- When vendoring is enabled, this manifest is used as a source of module version information, as reported by
Vendoring:
- enabled by default if the go version in the main module's
go.mod
file is 1.14 or higher. - To explicitly enable vendoring, invoke the go command with the flag
-mod=vendor
.
When vendoring is enabled, build commands like go build
and go test
load packages from the vendor
directory instead of accessing the network or the local module cache.
How to build CLI applications in Go?
Use Cobra (https://github.com/spf13/cobra), which is used in Kubernetes.
And use Viper (https://github.com/spf13/viper) to manage configurations.
How to get env variables in Go?
Use os.LookupEnv()
.
How to distinguish 0 and not present?
if seconds, ok := timeZone[tz]; ok {
return seconds
}
test if exists:
_, present := timeZone[tz]
Is Go Object Oriented?
Go is Object Oriented, but not in the usual way.
- no classes (methods may be declared on any type).
- no subtype inheritance.
- interfaces are satisfied implicitly (structural typing).
How to check if executables are on PATH?
import (
"os/exec"
)
func checkExecutableOnPath(cmd string) error {
if _, err := exec.LookPath(cmd); err != nil {
// Example error:
// exec: "cmd": executable file not found in $PATH
return err
}
return nil
}
Is GOPATH deprecated?
Evolution: GOPATH
=> Modules => Workspaces
GOPATH
had been replaced by modules. In 2014, Go development was entirely based on GOPATH
. Modules were an answer to many issues around GOPATH
. They gave more control to projects on how to track and manage dependencies, and were overall a great step forward.
Multi-module workspaces: With multi-module workspaces, you can tell the Go command that you’re writing code in multiple modules at the same time and easily build and run code in those modules. Once enrolled in a workspace, Go tools had enough information to work in any directory structure and across modules, without GOPATH or symlinks or other dirty tricks. Use go.work
to specify a workspace. (Created by go work init PATH
). The go.work
file has similar syntax to go.mod
.