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.
|
|
| 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.
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»
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.
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:
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.
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. |
|