Explore topic-wise InterviewSolutions in Current Affairs.

This section includes 7 InterviewSolutions, each offering curated multiple-choice questions to sharpen your Current Affairs knowledge and support exam preparation. Choose a topic below to get started.

1.

What do you understand by byte and rune data types? How are they represented?

Answer»

byte and rune are TWO integer types that are aliases for uint8 and int32 types respectively.
The byte represents ASCII characters WHEREAS the rune represents a single Unicode CHARACTER which is UTF-8 encoded by default.

  • The characters or rune literals can be represented by enclosing in single quotes like 'a','b','\n'.
  • Rune is also called a Code POINT and can also be a numeric value. For example, 0x61 in HEXADECIMAL corresponds to the rune literal a.
2.

What do you understand by variadic functions in Go?

Answer»

The function that takes a variable number of arguments is called a variadic function. We can pass zero or more PARAMETERS in the variadic function. The best example of a variadic function is fmt.Printf which requires one fixed argument as the first parameter and it can accept any arguments.

  • The syntax for the variadic function isHere, we see that the type of the last parameter is preceded by the ellipsis symbol (...) which indicates that the function can take any number of parameters if the type is specified.
  • Inside the variadic function, the ... type can be visualised as a slice. We can also pass the existing slice (or MULTIPLE slices) of the mentioned type to the function as a second parameter. When no values are passed in variadic function, the slice is treated as nil.
  • These functions are GENERALLY used for string formatting.
  • Variadic parameter can not be specified as return value, but we can return the variable of type slice from the function.

Consider an example code below:

FUNC function_name(arg1, arg2...type)type{ // Some statements}package main import( "fmt" "strings") // Variadic function to join strings and separate them with hyphenfunc joinstring(element...string)string{ return strings.Join(element, "-")} func main() { // To demonstrate zero argument fmt.Println(joinstring()) // To demonstrate multiple arguments fmt.Println(joinstring("Interview", "Bit")) fmt.Println(joinstring("Golang", "Interview", "Questions")) }

Here, we have a variadic function called joinstring that takes a variable number of arguments of a type string. We are trying to join the arguments separated by the hyphen symbol. We are demonstrating the variadic function behaviour by first passing 0 arguments and then passing multiple arguments to the function. The output of this code is:

Interview-BitGolang-Interview-Questions
3.

What do you understand by Shadowing in Go?

Answer»

Shadowing is a principle when a variable overrides a variable in a more specific scope. This means that when a variable is declared in an inner scope having the same data type and name in the outer scope, the variable is said to be shadowed. The outer variable is declared before the shadowed variable.

Consider a code snippet as shown below:

VAR numOfCars = 2 // Line 1type Car struct{ name string model string color string}cars:= [{ name:"TOYOTA", model:"Corolla", color:"red" }, { name:"Toyota", model:"Innova", color:"gray" }]func countRedCars(){ for i:=0; i<numOfCars; i++{ if cars[i].color == "red" { numOfCars +=1 // Line 2 fmt.Println("Inside countRedCars method ", numOfCars) //Line 3 } } }

Here, we have a function called countRedCars where we will be counting the red cars. We have the numOfCars variable defined at the beginning indicated by the Line 1 COMMENT. Inside the countRedCars method, we have an if STATEMENT that checks whether the colour is red and if red then increments the numOfCars by 1. The interesting POINT here is that the value of the numCars variable after the end of the if statement will not be affecting the value of the numOfCars variable in the outer scope.

4.

How can you sort a slice of custom structs with the help of an example?

Answer»

We can sort slices of custom structs by using sort.Sort and sort.Stable FUNCTIONS. These methods sort any collection that implements sort.Interface interface that has Len(), Less() and Swap() methods as shown in the code below:

type Interface interface { // Find number of elements in collection Len() int // Less method is used for IDENTIFYING which elements among index i and j are lesser and is used for sorting Less(i, j int) bool // Swap method is used for swapping elements with indexes i and j Swap(i, j int)}

Consider an example of a HUMAN Struct having name and age attributes.

type Human struct { name STRING age int}

Also, consider we have a slice of struct Human of type AgeFactor that needs to be sorted based on age. The AgeFactor implements the methods of the sort.Interface. Then we can call sort.Sort() method on the AUDIENCE as shown in the below code:

// AgeFactor implements sort.Interface that sorts the slice based on age field.type AgeFactor []Humanfunc (a AgeFactor) Len() int { return len(a) }func (a AgeFactor) Less(i, j int) bool { return a[i].age < a[j].age }func (a AgeFactor) Swap(i, j int) { a[i], a[j] = a[j], a[i] }func main() { audience := []Human{ {"Alice", 35}, {"Bob", 45}, {"James", 25}, } sort.Sort(AgeFactor(audience)) fmt.Println(audience) }

This code would output:

[{James 25} {Alice 35} {Bob 45}]
5.

Which is safer for concurrent data access? Channels or Maps?

Answer»

Channels are safe for concurrent ACCESS because they have blocking/locking mechanisms that do not LET goroutines share MEMORY in the presence of multiple threads.

Maps are unsafe because they do not have locking mechanisms. While using maps, we have to use explicit locking mechanisms like mutex for safely SENDING data through goroutines.

6.

In Go, are there any good error handling practices?

Answer»

In Go, the errors are nothing but an INTERFACE type where any type implementing the single Error() METHOD is considered as an error. Go does not have try/catch methods as in other programming languages for handling the errors. They are instead RETURNED as normal values. Following is the syntax for creating the error interface:

type error_name interface { Error() string}

We use this whenever we apprehend that there are possibilities where a function can go wrong during type conversions or network calls. The function should return an error as its return variable if things go wrong. The caller has to check this error VALUE and IDENTIFY the error. Any value other than nil is termed as an error.

As part of good error handling practices, guard classes should be used over if-else statements. They should also be wrapped in a meaningful way as they can be passed up in the call stack. Errors of the same types should not be logged or handled multiple times.

7.

How is GoPATH different from GoROOT variables in Go?

Answer»

The GoPATH variable is an environment variable that is used for symbolizing the directories out of $GoROOT which combines the source and the BINARIES of GO Projects. The GoROOT variable determines where the Go SDK is located. We do not have to MODIFY the variable unless we plan to use multiple Go versions. The GoPATH determines the root of the workspace whereas the GoROOT determines the LOCATION of Go SDK.

8.

How can we copy a slice and a map in Go?

Answer»
  • To copy a slice: We can use the built-in method CALLED copy() as shown below:
slice1 := []int{1, 2}slice2 := []int{3, 4}slice3 := slice1copy(slice1, slice2)fmt.Println(slice1, slice2, slice3)

In the above example, we are copying the value of slice2 into slice1 and we are using the variable slice3 for holding a REFERENCE to the original slice to check if the slice has been copied or not. The output of the above code would be:

[3 4] [3 4] [3 4]

If we want to copy the slice description alone and not the contents, then we can do it by using the = operator as shown in the code below:

slice1 := []int{1, 2}slice2 := []int{3, 4}slice3 := slice1slice1 = slice2fmt.Println(slice1, slice2, slice3)

The output of the code will be:

[3 4] [3 4] [1 2]

Here, we can see that the contents of slice3 are not changed due to the = operator.

  • To copy a MAP in Go: We can copy a map by traversing the keys of the map. There is no built-in method to copy the map. The code for achieving this will be:
MAP1 := map[string]bool{"Interview": true, "Bit": true}map2 := make(map[string]bool)for key, value := RANGE map1 { map2[key] = value}

From this code, we are iterating the contents of map1 and then adding the values to map2 to the corresponding key.

If we want to copy just the description and not the content of the map, we can again use the = operator as shown below:

map1 := map[string]bool{"Interview": true, "Bit": true}map2 := map[string]bool{"Interview": true, "Questions": true}map3 := map1map1 = map2 //copy descriptionfmt.Println(map1, map2, map3)

The output of the below code would be:

map[Interview:true Questions:true] map[Interview:true Questions:true] map[Interview:true Bit:true]
9.

What are the uses of an empty struct?

Answer»

Empty struct is used when we want to SAVE memories. This is because they do not consume any memory for the values. The syntax for an empty struct is:

a := struct{}{}

The size of empty struct would return 0 when using println(unsafe.Sizeof(a))

The important use of empty struct is to show the developer that we do not have any value. The purpose is purely informational. Some of the examples where the empty struct is useful are as follows:

  • While implementing a data set: We can use the empty struct to implement a dataset. Consider an example as shown below.
map_obj := make(map[string]struct{})for _, value := range []string{"interviewbit", "golang", "QUESTIONS"} { map_obj[value] = struct{}{}}fmt.Println(map_obj)

The output of this code would be:

map[interviewbit:{} golang:{} questions:{}]

Here, we are initializing the value of a key to an empty struct and initializing the map_obj to an empty struct.

  • In graph traversals in the map of tracking visited vertices. For example, consider the below piece of code where we are initializing the value of vertex visited empty struct.
visited := make(map[string]struct{})for _, isExists := visited[v]; !isExists { // First time VISITING a vertex. visited[v] = struct{}{}}
  • When a CHANNEL needs to send a signal of an event without the need for sending any data. From the below piece of code, we can see that we are sending a signal using sending empty struct to the channel which is sent to the workerRoutine.
func workerRoutine(ch chan struct{}) { // Receive message from main program. <-ch println("Signal Received") // Send a message to the main program. close(ch)}func main() { //Create channel ch := make(chan struct{}) //define workerRoutine GO workerRoutine(ch) // Send signal to worker goroutine ch <- struct{}{} // Receive a message from the workerRoutine. <-ch println(“Signal Received") }

The output of the code would be:

Signal ReceivedSignal Received
10.

Is the usage of Global Variables in programs implementing goroutines recommended?

Answer»

Using global VARIABLES in GOROUTINES is not RECOMMENDED because it can be accessed and modified by multiple goroutines concurrently. This can lead to UNEXPECTED and ARBITRARY results.

11.

How will you check the type of a variable at runtime in Go?

Answer»

In GO, we can USE a special type of switch for checking the VARIABLE type at runtime. This switch statement is called a “type switch”.

Consider the following piece of code where we are checking for the type of variable v and performing some set of operations.

switch v := param.(type) { DEFAULT: fmt.Printf("Unexpected type %T", v)case uint64: fmt.Println("Integer type")case string: fmt.Println("String type")}

In the above code, we are checking for the type of variable v, if the type of variable is uint64, then the code prints “Integer type”. If the type of variable is a string, the code prints “String type”. If the type doesn't MATCH, the default block is executed and it runs the statements in the default block.

12.

What do you understand by Type Assertion in Go?

Answer»

The TYPE assertion TAKES the interface value and retrieves the value of the specified explicit data type. The syntax of Type Assertion is:

t := i.(T)

Here, the statement ASSERTS that the interface value i has the CONCRETE type T and assigns the value of type T to the VARIABLE t. In case i does not have concrete type T, then the statement will result in panic.

For testing, if an interface has the concrete type, we can do it by making use of two values returned by type assertion. One value is the underlying value and the other is a bool value that tells if the assertion is completed or not. The syntax would be:

t, isSuccess := i.(T)

Here, if the interface value i have T, then the underlying value will be assigned to t and the value of isSuccess becomes true. Else, the isSuccess statement would be false and the value of t would have the zero value corresponding to type T. This ensures there is no panic if the assertion fails.

13.

Can you format a string without printing?

Answer»

Yes, we can do that by using the Sprintf command as shown in the example below:

RETURN fmt.Sprintf ("Size: %d MB.", 50)

The fmt.Sprintf function formats a string and returns the string WITHOUT PRINTING it.

14.

What do you understand by each of the functions demo_func() as shown in the below code?

Answer»

//DemoStruct definitiontype DemoStruct struct { Val int}//A.func demo_func() DemoStruct { return DemoStruct{Val: 1}}//B.func demo_func() *DemoStruct { return &DemoStruct{}}//C.func demo_func(s *DemoStruct) { s.Val = 1}

A. Since the function has a return type of the struct, the function RETURNS a copy of the struct by setting the value as 1.
B. Since the function returns *DemoStruct, which is a pointer to the struct, it returns a pointer to the struct value created within the function.
C. Since the function expects the existing struct object as a PARAMETER and in the function, we are setting the value of its ATTRIBUTE, at the END of execution the value of Val variable of the struct object is set to 1.

Previous Next