Crack the top 50 Golang interview questions
Tags: go, career, tutorial, learning
Published: 2021-03-18 19:02:03

 The Go programming language, or [Golang](https://www.educative.io/blog/golang-tutorial), is an open-source programming language similar to C but is optimized for quick compiling, seamless concurrency, and developer ease of use. 

This language was created and adopted by Google but has been gaining popularity in other companies in recent years as the demand for concurrent, networked programs is increasing.


Whether you're preparing for a [Google job interview](https://www.educative.io/blog/google-coding-interview) or just want to remain a cutting edge developer, Go is the right choice for you. Today, we'll help you practice your Go skills with 50 of the most important Go questions and answers.

 

**Here’s what we’ll cover today:**

* [Questions on Golang Basics](#basics)
* [Intermediate Golang Questions](#intermediate)
* [Coding challenges in Golang](#challenges)
* [Golang Concurrency Questions](#concurrency)
* [25 More Golang Questions](#more)
* [Next steps for your learning](#next)

 

<br>

<h4><b> Learn Go in half the time</b></h4>


 

Go is known for its concurrency capabilities. Stand out from the crowd with hands-on experience using the latest Go concurrency techniques.



<b>[Mastering Concurrency in Go](https://www.educative.io/courses/mastering-concurrency-in-go)</b>
<br>

 

<a name="basics"></a>

 

## Questions on Language Basics 

<bR>

### 1. What are the benefits of using Go compared to other languages?

- Unlike other languages which started as academic experiments, Go code is pragmatically designed. Every feature and syntax decision is engineered to make life easier for the programmer.

- Golang is optimized for concurrency and works well at scale.

- Golang is often considered more readable than other languages due to a single standard code format.

- Automatic garbage collection is notably more efficient than Java or Python because it executes concurrently alongside the program.

<bR>

### 2. What are string literals?

A string literal is a string constant formed by concatenating characters. The two forms of string literal are raw and interpreted string literals.

 Raw string literals are written within backticks (`foo`) and are filled with uninterpreted UTF-8 characters. Interpreted string literals are what we commonly think of as strings, written within double quotes and containing any character except newline and unfinished double quotes. 

<bR>

### 3. What data types does Golang use?

Golang uses the following types:

- Method 
- Boolean 
- Numeric 
- String 
- Array 
- Slice 
- Struct 
- Pointer 
- Function 
- Interface 
- Map 
- Channel 

<bR>

### 4. What are packages in a Go program?

Packages (`pkg`) 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: 

```go
package <packagename>
```

You can import and export packages to reuse exported functions or types using:

```go
import <packagename>
```

Golang's standard package is `fmt`, which contains formatting and printing functionalities like `Println()`. 

<bR>

### 5. What form of type conversion does Go support? Convert an integer to a float. 

Go supports explicit type conversion to satisfy its strict typing requirements. 

```go
i := 55      //int

j := 67.8    //float64

sum := i + int(j) //j is converted to int
```

<bR>

### 6. What is a goroutine? How do you stop it?

A [goroutine](https://www.educative.io/blog/golang-tutorial#goroutine) is a function or method that executes concurrently alongside any other goroutines using a special goroutine thread. Goroutine threads are more lightweight than standard threads, with most Golang programs using thousands of goroutines at once.

To create a goroutine, add the `go` keyword before the function declaration.

```go
go f(x, y, z)
```

You can stop a goroutine by sending it a signal channel. Goroutines can only respond to signals if told to check, so you'll need to include checks in logical places such as at the top of your `for` loop.

```go
package main
func main() {
  quit := make(chan bool)
  go func() {
    for {
        select {
        case <-quit:
            return
        default:
            // …
        }
  }
}()
// …
quit <- true
}
```

### 7. How do you check a variable type at runtime?

The Type Switch is the best way to check a variable's type at runtime. The Type Switch evaluates variables by type rather than value. Each Switch contains at least one `case`, which acts as a conditional statement,  and a `default` case, which executes if none of the cases are true.

 For example, you could create a Type Switch that checks if interface value `i` contains the type `int`  or `string`:

```go
package main

import "fmt"

func do(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Printf("Double %v is %v\n", v, v*2)
	case string:
		fmt.Printf("%q is %v bytes long\n", v, len(v))
	default:
		fmt.Printf("I don't know  type %T!\n", v)
	}
}

func main() {
	do(21)
	do("hello")
	do(true)
}
```

<bR>

### 8. How do you concatenate strings?

The easiest way to [concatenate strings](https://www.educative.io/blog/concatenate-string-c) is to use the concatenation operator (`+`), which allows you to add strings as you would numerical values.

```go
package main
import "fmt"
  
func main() { 
  
    // Creating and initializing strings 
    // using var keyword 
    var str1 string 
    str1 = "Hello "
  
    var str2 string 
    str2 = "Reader!"
  
    // Concatenating strings 
    // Using + operator 
    fmt.Println("New string 1: ", str1+str2) 
  
    // Creating and initializing strings 
    // Using shorthand declaration 
    str3 := "Welcome"
    str4 := "Educative.io"
  
    // Concatenating strings 
    // Using + operator 
    result := str3 + " to " + str4 
  
    fmt.Println("New string 2: ", result) 
  
} 
```

<br>

<a name="intermediate"></a>

## Intermediate Golang Questions

<bR>
 

### 9. Explain the steps of testing with Golang.

Golang supports automated testing of packages with custom testing suites. 

To create a new suite, create a file that ends with `_test.go` and includes a `TestXxx` function, where `Xxx` is replaced with the name of the feature you're testing. For example, a function that tests login capabilities would be called `TestLogin`. 

You then place the testing suite file in the same package as the file you wish to test. The test file will be skipped on regular execution but will run when you enter the `go test` command.

<bR>

### 10. What are function closures?

Function closures is a function value that references variables from outside its body. The function may access and assign values to the referenced variables. 

For example: `adder()` returns a closure, which is each bound to its own referenced `sum` variable.

```go
package main

import "fmt"

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}
```


<bR>

### 11. How do we perform inheritance with Golang?

This is a bit of a trick question: there is no [inheritance](https://www.educative.io/blog/java-inheritance-tutorial) in Golang because it does not support classes. 

However, you can mimic inheritance behavior using composition to use an existing struct object to define a starting behavior of a new object. Once the new object is created, functionality can be extended beyond the original struct.

```go
type Animal struct {
	// …
}

func (a *Animal) Eat()   { … }
func (a *Animal) Sleep() { … }
func (a *Animal) Run() { … }

type Dog struct {
	Animal
	// …
}
```

The `Animal` struct contains `Eat()`, `Sleep()`, and `Run()` functions. These functions are embedded into the child struct `Dog` by simply listing the struct at the top of the implementation of `Dog`.

<bR>

### 12. Explain Go interfaces. What are they and how do they work?

Interfaces are a special type in Go that define a set of method signatures but do not provide implementations. Values of type 
interface can hold any value that implements those methods.

Interfaces essentially act as placeholders for methods that will have multiple implementations based on what object is using them. 

For example, you could implement a `geometry` interface that defines that all shapes that use this interface must have an implementation of `area()` and `perim()`.

```go	
type geometry interface {
    area() float64
    perim() float64
}
```

<bR>

### 13. 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

> For example: In the statement `x =20`, `x` is an lvalue and `20` is an rvalue.

**Rvalue**

- Represents a data value stored in memory

- Represents a constant value

- Always appears on the `=` operator's right side.

> For example, The statement `10 = 20` is invalid because there is an rvalue (`10`) left of the `=` operator.

<bR>

### 14. What are the looping constructs in Go?

Go has only one looping construct: the `for` loop. The `for` loop has 3 components separated by semicolons:

- The `Init` statement, which is executed before the loop begins. It's often a variable declaration only visible within the scope of the `for` loop. 

- The condition expression, which is evaluated as a Boolean before each iteration to determine if the loop should continue.

- The post statement, which is executed at the end of each iteration.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iw4ghtal13nh7sb0hd3w.PNG)

```go
package main
import "fmt"
func main() {
    sum := 0
    for i := 0; i < 10; i++ {
        sum += i
    }
    fmt.Println(sum)
}
```

<bR>

### 15. Can you return multiple values from a function?

Yes. A Go function can return multiple values, each separated by commas in the `return` statement.

```go
package main

import "fmt"

func foo() (string, string) {
   return "two", "values"
}

func main() {
   fmt.Println(foo())

}
```


<br>

#### Keep practicing Go.


Hands-on practice is essential to learning Golang. 
Educative's text-based courses feature live coding environments and professional Go developer tips to help you pick up the language in half the time.


<b>[Mastering Concurrency in Go](https://www.educative.io/courses/mastering-concurrency-in-go)</b>

<br>


<a name="coding"></a>

## Coding challenges with Golang
 

<Br>

 

### 16. Implement a Stack (LIFO)

Implement a stack structure with pop, append, and print top functionalities.

**Solution**

You can implement a stack using a slice object.

```go
package main

import "fmt"

func main() {

// Create

var stack []string

// Push

stack = append(stack, "world!")

stack = append(stack, "Hello ")

for len(stack) > 0 {

        // Print top

        n := len(stack) - 1

        fmt.Print(stack[n])

        // Pop

        stack = stack[:n]

}

// Output: Hello world!

}
```

First, we use the built-in `append()` function to implement the append behavior. Then we use `len(stack)-1` to select the top of the stack and print. 

For pop, we set the new length of the stack to the position of the printed top value, `len(stack)-1`.

<bR>

### 17. Print all permutations of a slice characters or string

Implement the `perm()` function that accepts a slice or string and prints all possible combinations of characters.

**Solution**

```go
package main
import "fmt"

// Perm calls f with each permutation of a.

func Perm(a []rune, f func([]rune)) {
        perm(a, f, 0)
}

// Permute the values at index i to len(a)-1.

func perm(a []rune, f func([]rune), i int) {
        if i > len(a) {
                f(a)
                return
        }
        perm(a, f, i+1)
        for j := i + 1; j < len(a); j++ {
                a[i], a[j] = a[j], a[i]
                perm(a, f, i+1)
                a[i], a[j] = a[j], a[i]
        }
}

func main() {
Perm([]rune("abc"), func(a []rune) {
        fmt.Println(string(a))
})
}
```

We use rune types to handle both slices and strings. Runes are Unicode code points and can therefore parse strings and slices equally.

<bR>

### 18. Swap the values of two variables without a temporary variable

Implement `swap()` which swaps the value of two variables without using a third variable. 

**Solution**

```go
package main

import "fmt"

func main() {
   fmt.Println(swap())
}

func swap() []int {
      a, b := 15, 10
   b, a = a, b
   return []int{a, b}
}
```

While this may be tricky in other languages, Go makes it easy. 

We can simply include the statement `b, a = a, b`, what data the variable references without engaging with either value.

<bR>

### 19. Implement min and max behavior

Implement `Min(x, y int)` and `Max(x, y int)` functions that take two integers and return the lesser or greater value, respectively. 

**Solution**

By default, Go only supports min and max for floats using `math.min` and `math.max`. You'll have to create your own implementations to make it work for integers.

```go
package main

import "fmt"

// Min returns the smaller of x or y.

func Min(x, y int) int {
        if x > y {
                return y
        }
        return x
}

// Max returns the larger of x or y.

func Max(x, y int) int {
        if x < y {
                return y
        }
        return x
}

func main() { 
    fmt.Println(Min(5,10))
    fmt.Println(Max(5,10))
}
```

<bR>

### 20. Reverse the order of a slice

Implement function `reverse` that takes a slice of integers and reverses the slice in place without using a temporary slice.

**Solution**

```go
package main

import "fmt"

func reverse(sw []int) {
        for a, b := 0, len(sw)-1; a < b; a, b = a+1, b-1 {
                sw[a], sw[b] = sw[b], sw[a]
        } 
}

func main() { 
    x := []int{3, 2, 1} 
    reverse(x)
    fmt.Println(x)
}
```

Our for loop swaps the values of each element in the slice will slide from left to right. Eventually, all elements will be reversed.

<bR>

### 21. What is the easiest way to check if a slice is empty?

Create a program that checks if a slice is empty. Find the simplest solution.

**Solution**

The easiest way to check if a slice is empty is to use the built-in `len()` function, which returns the length of a slice. If `len(slice) == 0`, then you know the slice is empty.

For example:

```go
package main

import "fmt"

func main() {
  r := [3]int{1, 2, 3}

  if len(r) == 0 {
    fmt.Println("Empty!")
    
  } else {
    fmt.Println("Not Empty!")
  }
}
```


<bR>

### 22. Format a string without printing it

Find the easiest way to format a string with variables without printing the value.

**Solution**

The easiest way to format without printing is to use the `fmt.Sprintf()`, which returns a string without printing it. 

For example:

```go
package main

import "fmt"

func main() {
  s := fmt.Sprintf("Size: %d MB.", 85)
  fmt.Println(s)
}
```

<br>

 

<a name="concurrency"></a>

 

## Golang Concurrency Questions
 

<br>

 

### 23. Explain the difference between concurrent and parallelism in Golang

[Concurrency](https://www.educative.io/blog/multithreading-and-concurrency-fundamentals) is when your program can *handle* multiple tasks at once while parallelism is when your program can *execute* multiple tasks at once using multiple processors. 

In other words, concurrency is a property of a program that allows you to have multiple tasks in progress at the same time, but not necessarily executing at the same time. Parallelism is a runtime property where two or more tasks are executed at the same time.

Parallelism can therefore be a means to achieve the property of concurrency, but it is just one of many means available to you.

The key tools for concurrency in Golang are goroutines and channels. Goroutines are concurrent lightweight threads while channels allow goroutines to communicate with each other during execution.

<Br>

### 24. Merge Sort 

Implement a concurrent [Merge Sort](https://www.educative.io/blog/algorithms-101-merge-sort-quicksort) solution using goroutines and channels. 

You can use this sequential Merge Sort implementation as a starting point:

```go
package main
import "fmt"
         
func Merge(left, right [] int) [] int{
  merged := make([] int, 0, len(left) + len(right))

  for len(left) > 0 || len(right) > 0{

    if len(left) == 0 {
      return append(merged,right...)

    }else if len(right) == 0 {
      return append(merged,left...)

    }else if left[0] < right[0] {
      merged = append(merged, left[0])
      left = left[1:]

    }else{
      merged = append(merged, right [0])
      right = right[1:]
    }
  }
  return merged
}

func MergeSort(data [] int) [] int {
  if len(data) <= 1 {
    return data
  }
  mid := len(data)/2
  left := MergeSort(data[:mid])
  right := MergeSort(data[mid:])
  return Merge(left,right)
}

func main(){
  data := [] int{9,4,3,6,1,2,10,5,7,8}
  fmt.Printf("%v\n%v\n", data, MergeSort(data))
}
```

**Solution**

```go
package main
import "fmt"

func Merge(left, right [] int) [] int{
  merged := make([] int, 0, len(left) + len(right))
  for len(left) > 0 || len(right) > 0{
    if len(left) == 0 {
      return append(merged,right...)
    }else if len(right) == 0 {
      return append(merged,left...)
    }else if left[0] < right[0] {
      merged = append(merged, left[0])
      left = left[1:]
    }else{
      merged = append(merged, right [0])
      right = right[1:]
    }
  }
  return merged
}

func MergeSort(data [] int) [] int {
  if len(data) <= 1 {
    return data
  }
  done := make(chan bool)
  mid := len(data)/2
  var left [] int
  go func(){
    left = MergeSort(data[:mid])
    done <- true
  }()
  right := MergeSort(data[mid:])
  <-done
  return Merge(left,right)
}

func main(){
  data := [] int{9,4,3,6,1,2,10,5,7,8}
  fmt.Printf("%v\n%v\n", data, MergeSort(data))
}
```

Firstly, in merge sort, we keep dividing our array recursively into the `right` side and the `left` side and call the `MergeSort` function on both sides from **line 30** to **line 34**.

Now we have to make sure that `Merge(left,right)` is executed after we get return values from both the recursive calls, i.e. both the `left` and `right` must be updated before `Merge(left,right)` can be executable. Hence, we introduce a channel of type `bool` on **line 26** and send `true` on it as soon as `left = MergeSort(data[:mid])` is executed (**line 32**). 

The `<-done` operation blocks the code on **line 35** before the statement `Merge(left,right)` so that it does not proceed until our goroutine has finished. After the goroutine has finished and we receive `true` on the `done` channel, the code proceeds forward to `Merge(left,right)` statement on **line 36**.

<br>

### 25. Sum of Squares 

Implement the `SumOfSquares` function which takes an integer, `c` and returns the sum of all squares between 1 and `c`. You'll need to use `select` statements, goroutines, and channels.

For example, entering `5` would return `55` because $1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55$

You can use the following code as a starting point:

```go
package main

import "fmt"

func SumOfSquares(c, quit chan int) {

// your code here

}

func main() {

  mychannel := make(chan int)

  quitchannel:= make(chan int)

  sum:= 0

  go func() {
    for i := 0; i < 6; i++ {
      sum += <-mychannel
    }
    fmt.Println(sum)
  }()
  SumOfSquares(mychannel, quitchannel)
}
```

**Solution**

```go
package main
import "fmt"

func SumOfSquares(c, quit chan int) {
  y := 1
  for {
    select {
    case c <- (y*y):
      y++
    case <-quit:
      return
    }
  }
}

func main() {
  mychannel := make(chan int)
  quitchannel:= make(chan int)
  sum:= 0
  go func() {
    for i := 1; i <= 5; i++ {
      sum += <-mychannel
    }
    fmt.Println(sum)
    quitchannel <- 0
  }()
  SumOfSquares(mychannel, quitchannel)
}
```

Take a look at our `SumOfSquares` function. First, on **line 4**,  we declare a variable `y` and then jump to the `For-Select` loop. We have two cases in our select statements:

- `case c <- (y*y)`: This is to send the square of `y` through the channel `c`, which is received in the goroutine created in the main routine.

- `case <-quit`: This is to receive a message from the main routine that will return from the function.

<br>

 

<a name="more"></a>

 

## 25 More Golang Questions

**26.** What is a workspace?

**27.** What is CGO? When would you want to use it?

**28.** What is shadowing?

**29.** What is the purpose of a GOPATH environment variable?

**30.** How are pointers used in Go?

**31.** What types of pointers does Go have?

**32.** Why is Go often called a "Post-OOP" language?

**33.** Does Go have exceptions? How does Go handle errors?

**34.** When would you use a break statement in Go?

**35.** How do untyped constants interact with Go's typing system?

**36.** What is the difference between `=` and `:=` in Go?

**37.** What is the difference between C arrays and Go slices?

**38.** Does Go support method overloading?

**39.** What makes Go so fast?

**40.** How do you implement command-line arguments in Go?

**41.**  How does Go handle dependencies?

**42.** What is a unique benefit of Go's compiler?

**43.** What is in the src directory?

**44.** Name one Go feature that would be helpful for DevOps.

**45.** What does GOROOT point to?

**46.** What makes Go compile quickly?

**47.** Implement a binary search tree data structure in Go.

**48.** What does it mean when people say Go has a "rich standard library"?

**49.** What is an advantage of Go evaluating implicit types at compile time?

**50.** Describe the crypto capabilities of Go.

<br>

 

<a name="next"></a>

 

## Next steps for your learning

Great job on those practice questions! Go is a rising language and hands-on practice like this is the key to picking it up fast. To best prepare for interviews, you'll want to:
* Develop a detailed study plan 
* Practice Go problems on a whiteboard 
* Learn how to articulate your thought process aloud 
* Prepare for behavioral interviews

 
To help you learn even faster, Educative has created [**Mastering Concurrency in Go**](https://www.educative.io/courses/mastering-concurrency-in-go). This course includes in-depth explanations and practice projects to show you how to get the most out of Go's awesome concurrency capabilities. 

By the end of the course, you'll have the practical Go experience you'll need to pick up this language in half the time.


*Happy learning!* 

<Br>

### Continue reading about Golang

- [How to become a Golang developer: 6 step career guide](https://www.educative.io/blog/become-golang-developer)
- [Getting started with Golang: a tutorial for beginners](https://www.educative.io/blog/golang-tutorial)
- [The 6 Best Programming Languages to Learn in 2021](https://www.educative.io/blog/best-programming-language-learn-2021)