Monday, 1 December 2025

Golang Intermediate Interview Q&A

1. How do you handle panics and recover from them in Go?

To handle panics and recover from them in Go, the built-in panic() and recover() functions can be used. When an error occurs, panic() is called and the program execution stops. You can use the defer statement to call recover(), which stops the panic and resumes execution from the point of the nearest enclosing function call, after all deferred functions have been run.

It's important to note that you should only use panic and recover for exceptional cases such as when a program encounters unexpected errors. It's not meant to handle normal control flow or act as a replacement for checking errors.

Using these functions properly can help you ensure programs remain robust and reliable.


2. Explain the defer statement in Golang. Give an example of a deferred function’s call.


The defer statement in Golang is used to postpone the execution of a function until the surrounding function completes. It is often used when you want to make sure some cleanup tasks are performed before exiting a function, regardless of errors or other conditions.

Here's an example of a deferred function's call:


The cleanup function will be executed right before the main function exits, ensuring that cleanup tasks are always performed.


3. How do you create and use a package in Go?

  • Create a directory for your package. Use a meaningful name that represents the package's functionality.
  • Inside the directory, create a Go source file. The name of the file should match the directory name.
  • Add code to the source file, defining functions, variables, and types that make up your package.
  • At the top of your source file, add a package statement with the name of your package.
  • To use the package in another Go program, import it by using the package name, followed by the directory path.

4. What is the difference between a package and a module in Go?


In Go, a package is a collection of related Go source files that can be compiled together. It acts as a unit of distribution and code organization. It provides a way to reuse code across different projects and allows for encapsulation of functionality.

On the other hand, a module in Go is a collection of packages that are versioned together. It allows for managing dependencies and provides a way to ensure that the correct versions of packages are used in a project. It also facilitates versioning and dependency management.

In short, a package is a unit of code organization, while a module is a unit of versioning and dependency management in Go.


5. How do you create a custom type in Go?


Custom types are useful for improving code readability and creating abstractions. To create a custom type in Go, you can use the type keyword, followed by the name of your type and the underlying type it should be based on.

For example, if you want to create a custom type called Person based on the string type, you would use type Person string. You can also create a custom type based on a struct or any other built-in type in Go. Once your custom type is defined, you can use it like any other data type in your code.


6. What is the syntax for type casting in Go?


In Go, type casting is done using the Type(value) syntax. To convert a value to a specific type, you need to mention the desired type in parentheses, followed by the value you want to convert.

For example, if you want to convert an integer to a floating-point number, you can use the syntax float64(42). Similarly, if you want to convert a floating-point number to an integer, you can use the syntax int(3.14).

Keep in mind that type casting should be used carefully as it can result in data loss or unexpected behavior if done incorrectly.


7. How do you use the "blank identifier" in Go?


The blank identifier, represented by an underscore character, is used in Go as a placeholder for a variable or value that is not needed or used in code. It allows programmers to ignore an unused variable without generating a compiler warning.

If a function returns multiple values but only one of them needs to be used, you can use the blank identifier to discard the others. Additionally, it can be used in variable declarations to indicate that the variable is not needed for the code to compile.

Overall, the blank identifier is a helpful tool for reducing clutter in code when you don't need to use certain variables or values.


8. How do you create and use a pointer to a struct in Go?


To create and use a pointer to a struct in Go, define the struct type using the type keyword. Then, you declare a pointer variable by using an asterisk * before the struct type name.

For example, to create a pointer to a struct named Person, define the struct type as type Person struct { /* struct fields */ }, and then declare a pointer variable p using var p *Person.

To access the fields of the struct through the pointer, use the arrow “.” syntax. For example, to access the name field of the p pointer, use p.name.


9. How do you embed a struct in Go?


To embed a struct in Go, you only have to declare a field in a struct and assign it the value of another struct. This field with a struct value is then known as an embedded struct.

You can also access the embedded struct's fields by using dot notation with the parent struct. This allows you to reuse the fields and methods of the embedded struct without explicitly declaring them in the parent struct.

Additionally, you can use anonymous fields to embed a struct without specifying a name for the field. This helps to simplify the code and make it more concise.


10. How do you create and use a function closure in Go?


Closures are useful for creating private variables and to bind values to callback functions.

To create a function closure in Go, first define a function containing the variables you want to access and return it. Then, assign the function to a variable. This will create a closure where the variables within the function are accessible to the assigned variable and any functions returned by it.

To use the closure, call the assigned variable, which will execute the contained function. The inner variables will retain their values between function calls.


11. What is the syntax for creating and using a function literal in Go?


In Go, a function literal is created using the "func" keyword, followed by the formal parameters within parentheses, and the function body enclosed within curly braces. The syntax looks like this:


Function literals can also be passed as arguments to other functions or returned as values from functions, making them a powerful feature of Go's functional programming capabilities.


12. How do you use the "select" statement in Go?


The "select" statement in Go is used for multiplexing channels, allowing a Go program to handle multiple channels at once. With "select," you can send and receive data from multiple channels which allows for efficient communication between goroutines.

The basic syntax of "select" allows you to specify multiple channels and assign their input and output to different cases. It can also be used with the default case that executes if no other case is ready.

The "select" statement allows for powerful concurrent programming in Go and facilitates easier and more efficient communication between independently executing goroutines.


13. What is the syntax for creating and using a type assertion in Go?


In Go, a type assertion is used to extract a value of an underlying concrete type from an interface value. The syntax for creating and using a type assertion involves putting the keyword .(type) after the value that you want to assert the type of.

Here's an example:


In this example, val is asserted to be of type string. If successful, it is printed to the console. The second variable ok is used to determine if the assertion was successful or not.


14. What is the syntax for creating and using a type switch in Go?


In Go, a type switch allows you to determine the type of an interface variable at runtime and perform different actions depending on its type. The syntax for a type switch involves the 'switch' keyword, followed by the variable name in parentheses with type assertion.

Each case within the 'switch' statement defines a type preceded by the 'case' keyword. The keyword 'default' can also be used to define an action for any non-matching type. Within each case, you can perform operations specific to the type of the variable.

The syntax for creating and using a type switch in Go is relatively straightforward and allows for efficient code optimization based on different types of input.


15. What is the syntax for creating and using a type conversion in Go?

In Go, type conversion can be performed by specifying the desired type in parentheses, followed by the value or expression to be converted. The syntax for creating a type conversion is as follows:

var num float64 = 3.14

var intNum int = int(num)

In this example, there is a variable num of type float64 and we want to convert it to an int using type conversion. The intNum variable is assigned the value of num converted to an int. Type conversions can also be used within expressions to ensure that all operands are of the same type.


16. How do you use the "sync" package to protect shared data in Go?


The "sync" package in Go provides a set of tools that can be used to protect shared data from being accessed concurrently by multiple goroutines. One of the most popular ways to protect shared data is by using a mutex.

A mutex is a synchronization object that can be used to protect a resource so that only one goroutine can access it at a time. To use a mutex, you create a new instance of the sync.Mutex struct, and then use the Lock and Unlock methods to protect the critical section of code.

By doing this, you ensure that no two goroutines can access the shared data at the same time, which helps prevent data races and other synchronization issues.


17. How do you use the "sync/atomic" package to perform atomic operations in Go?


To use the "sync/atomic" package in Go, you need to import it into your code using the import statement. Once done, the package provides functions and types to perform atomic operations on variables.

To perform an atomic operation, define a variable of the desired type using one of the atomic types provided by the package (e.g., int32, int64). Then, use the atomic functions like atomic.LoadXXX and atomic.StoreXXX to atomically load and store values.

These atomic operations ensure that the operations on the variable are performed in an atomic manner, avoiding race conditions and guaranteeing data integrity.


18. How do you use the "context" package to carry around request-scoped values in Go?


There are a few steps involved to use the "context" package in Go to carry around request-scoped values:

  • Import the "context" package: import "context".
  • Create a new context with the context.Background() function: ctx := context.Background().
  • Add values to the context using the WithValue method: ctxWithValue := context.WithValue(ctx, key, value).
  • To retrieve the value from the context, use the Value method: val := ctxWithValue.Value(key).

Remember that the key needs to be unique to your application to avoid conflicts with other packages.

By using the "context" package, you can pass request-scoped values throughout your Go application easily.


19. How do you use the "net/http" package to build an HTTP server in Go?

To build an HTTP server in Go, you can use the built-in "net/http" package that provides a range of functions and methods to handle HTTP requests and responses.

To get started, define a handler function that takes in an HTTP response writer and request. Then, register the handler function with the "http" package that handles incoming requests and invokes the handler function.

With the "http" package, you can specify the port number, listen for incoming requests, and gracefully shut down the server. Overall, the "net/http" package offers a simple and effective way to quickly build HTTP servers in Go.


20. How do you use the "encoding/json" package to parse and generate JSON in Go?


To use the "encoding/json" package in Go, you have two main functions at your disposal: "json.Marshal" and "json.Unmarshal".

You can use "json.Marshal" to generate JSON from a Go data structure. This function takes Go data and encodes it into a JSON string you can then use as needed.

Meanwhile, you can use "json.Unmarshal" to parse JSON and convert it into Go data. This function takes a JSON string and decodes it into a Go data structure.

Both of these functions require you to define struct tags on your Go data structure to specify how the JSON should be formatted.

These functions are the key to effectively working with JSON in Go using the "encoding/json" package.


21. How do you use the "reflect" package to inspect the type and value of a variable in Go?

To use the "reflect" package in Go, import it using import "reflect". You can then inspect the type and value of a variable using the reflect.TypeOf() and reflect.ValueOf() functions, respectively.

For example, you can use reflect.TypeOf(x) to inspect the type of a variable x. This will return a reflect.Type object. Similarly, you can use reflect.ValueOf(x) to inspect the value of x. This will return a reflect.Value object.

The methods provided by these objects can be used to further inspect and manipulate the variable's type and value.


22. How do you use the "testing" package to write unit tests in Go?

To write unit tests in Go using the "testing" package, you first need to create a test file with a name that ends in _test.go. In this file, write functions that start with Test, followed by the name of the function you want to test, for example, TestAddition(). Then, inside the test function, write assertions using the t parameter that represents the testing.T type.

You can call specific functions or subtests within a test file using the go test command, followed by the package name or file name. go test runs all tests in all files, while go test -run=TestAddition runs only the TestAddition test.

The testing package includes a variety of useful functions, such as Errorf() and Fatal(), to help you write better tests.


23. How do you use the "errors" package to create and manipulate errors in Go?

Here are the steps to create and manipulate errors with the "errors" package:

  • Import the "errors" package into your code: import "errors".
  • Create a new error by using the errors.New() function and passing in a string describing the error: err := errors.New("Something went wrong").
  • Manipulate the error by checking its value. You can compare the error with another error using the errors.Is() function or retrieve the error message by calling err.Error().

24. How do you use the "net" package to implement networking protocols in Go?

The "net" package is a built-in Go library that provides basic networking functionality. It allows for communication over network protocols such as TCP, UDP, and Unix domain sockets.

To use this package, import it into your code and then create network connections using the functions provided by "net". For example, "net.Dial()" is used to establish a TCP connection to a server.

Other functions, such as "net.Listen()" and "net.Accept()", are used to create and accept incoming network connections. By utilizing the "net" package, you can easily implement networking protocols in Go programs with minimal effort.


25. How do you use the "time" package to handle dates and times in Go?


To use the "time" package in Go, first import it with import "time". This package provides functions and types to handle dates and times.

A few useful methods to perform various operations:

  • To get the current time, use time.Now().
  • To format it, use the Format() method, specifying the desired layout or format string such as time.Now().Format("2006-01-02 15:04:05").
  • To parse a string into a time value, use time.Parse() and provide the layout of the string. For example, time.Parse("2006-01-02", "2022-12-31") would parse the string "2022-12-31" into a time value.

You can perform other operations on time values, such as adding and subtracting durations using the Add() and Sub() methods, respectively.

Remember, the "time" package is very flexible and can handle various time-related tasks efficiently in Go.


26. How do you use the "math" and "math/rand" packages to perform mathematical and statistical operations in Go?

The "math" and "math/rand" packages are built into Go and provide extensive mathematical and statistical operation functionalities. The "math" package, for instance, offers fundamental mathematical constants such as Pi, mathematical functions for trigonometry, exponential, and logarithmic, as well as rounding and floating-point operations.

The "math/rand" package is specially designed to generate random numbers based on pseudo-random number generator algorithms. This package can be used for statistical simulations or for generating random passwords and encryption keys.

To use these packages, import them into your Go program. You can then call various functions and methods provided by the packages for their specific purposes.


27. How do you use the "crypto" package to perform cryptographic operations in Go?

The "crypto" package in Go provides a set of tools for performing cryptographic operations. To use it, you need to import the package using:

import "crypto"

You can then use the various functions provided by the package for cryptographic operations such as hashing, encryption, and decryption. For example, to generate a SHA-256 hash of a message, you can use the code:


This code will generate a SHA-256 hash of the message "Hello, world!" in hexadecimal format. The "crypto" package provides many other functions for performing different kinds of cryptographic operations.


28. How do you use the "os" package to interact with the operating system in Go?

In Go, the "os" package provides a way to interact with the operating system. You can use the package to perform operations like creating, opening, reading, writing, and deleting files and directories, among other things.

To use the "os" package, you need to import it using the import statement, after which you can access its functions and types. Some of the common functions that you can use are os.Open(), os.Create(), os.ReadDir(), os.Mkdir(), and os.RemoveAll(), among others.

Such functions allow you to work with files and directories and modify file attributes and access the terminal's environment variables, among other interactions with the operating system.


29. How do you use the "bufio" package to read and write buffered data in Go?

To use the bufio package in Go, you first need to import the package using the statement import "bufio". The bufio package provides buffered I/O operations for reading and writing data.

To read buffered data, create a new bufio.Reader object by passing an io.Reader object to the bufio.NewReader() function. You can then use methods like ReadString(), ReadBytes(), or ReadLine() to read the data.

To write buffered data, create a new bufio.Writer object by passing an io.Writer object to the bufio.NewWriter() function. You can then use methods like WriteString(), Write(), or Flush() to write the data. Remember to close the underlying io.Reader or io.Writer to properly release resources.


30. How do you use the "strings" package to manipulate strings in Go?

The “strings” package can be used in the following ways:

  • Use strings.Contains(str, substr) to check if a string contains a specific substring.
  • strings.HasPrefix(str, prefix) and strings.HasSuffix(str, suffix) can be used to check if a string starts or ends with a specific prefix/suffix.
  • strings.ToLower(str) and strings.ToUpper(str) can be used to convert a string to lowercase or uppercase.
  • strings.Replace(str, old, new, n) replaces all occurrences of a substring with a new substring.
  • strings.Split(str, sep) splits a string into a slice of substrings based on a separator.

31. How do you use the "bytes" package to manipulate byte slices in Go?

To use the "bytes" package in Go to manipulate byte slices, import the package using the import statement:

import "bytes"

Once the package is imported, you can perform various operations on byte slices.
Some commonly used functions in the "bytes" package include:

  • Join: Joins multiple byte slices into a single byte slice.
  • Split: Splits a byte slice into multiple byte slices based on a separator.
  • Contains: Checks if a byte slice contains another byte slice.
  • Replace: Replaces occurrences of a byte slice with another byte slice.
  • Index: Returns the index of the first occurrence of a byte slice.

With these functions, you can easily manipulate byte slices in Go using the "bytes" package.


32. How do you use the "encoding/binary" package to encode and decode binary data in Go?

In Go, the "encoding/binary" package is used to convert binary data to Go data types and vice versa. To encode binary data, you need to create a buffer object using the "bytes" package. Next, use the appropriate encoding function, such as binary.Write(), to encode the binary data into the buffer.

To decode binary data, create a buffer object. Then, use the appropriate decoding function, such as binary.Read(), to read the binary data into the buffer. The data can then be extracted from the buffer using the appropriate Go data type.

It’s important to ensure that the binary data is formatted correctly to prevent errors during encoding and decoding.


33. How do you use the "compress/gzip" package to compress and decompress data using the gzip algorithm in Go?

Compressing and decompressing data using the gzip algorithm entails the following steps:

  • Import the package into your code with import "compress/gzip"
  • To compress data, create a new gzip.Writer by passing an io.Writer as its parameter.
  • Write the data to be compressed using the Write method of the gzip.Writer.
  • Flush and close the gzip.Writer to finalize the compression.
  • To decompress data, create a new gzip.Reader by passing an io.Reader as its parameter.
  • Read the decompressed data using the Read method of the gzip.Reader.

34. How do you use the "database/sql" package to access a SQL database in Go?

Accessing a SQL database in Go with the "database/sql" package involves the following steps:

  • Import the database/sql package and the specific driver package for the database you want to connect to.
  • Open a connection to the database using the appropriate driver's Open function.
  • Use the DB object returned by the Open function to execute SQL queries or statements.
  • Handle errors properly using the Error method of the returned result or the CheckError function.
  • Close the connection when you're done using the database.

35. How do you use the "html/template" package to generate HTML templates in Go?

To begin using the "html/template" package in Go, you need to import it into your code and create a new template using the ParseFiles() function. This takes a string of one or more file paths as an argument.

Once you have your template, you can execute it using the Execute() method, passing in a Writer object as well as any data you want to render in the template. When defining the template, you use special syntax to indicate where you want values to be dynamically inserted. For example, {{.}} for the current value and {{range}} for iterating over a collection.


Thank you

No comments:

Post a Comment

Golang Advanced Interview Q&A