Go Introduction
Go Introduction
What is Go?
Go is a cross-platform, open source programming language
Go can be used to create high-performance applications
Go is a fast, statically typed, compiled language known for its
simplicity and efficiency
Go was developed at Google by Robert Griesemer, Rob Pike, and Ken
Thompson in 2007
Go's syntax is similar to C++
Channels, on the other hand, are used for communication and synchronization between
goroutines. They can be created using make and can be used to send and receive values.
To start a goroutine, simply prefix a function call with the go keyword. This will create a new
goroutine that executes the function concurrently. Channels can be used to share data
between goroutines, allowing them to communicate and synchronize.
By using goroutines and channels, Go provides a simple and efficient way to implement
concurrency in programs.
Go provides a built-in panic function to handle exceptional situations. When a panic occurs, it
stops the execution of the program and starts unwinding the stack, executing deferred
functions along the way. To recover from a panic, you can use the recover function in a
deferred function. This allows you to handle the panic gracefully and continue the program
execution.
4. How do you implement interfaces in Go?
Interfaces are implemented implicitly in Go. This means that you don't need to explicitly
declare that a type implements an interface. Instead, if a type satisfies all the methods defined
in an interface, it is considered to implement that interface.
This is done by first defining the interface type using the type keyword followed by the
interface name and the methods it should contain. The next step is creating a struct type or
any existing type that has all the methods required by the interface. Go compiler will
automatically recognize that type as implementing the interface.
Using interfaces can help you achieve greater flexibility and polymorphism in Go programs.
5. How do you optimize the performance of Go code?
These strategies can optimize Go code performance:
Minimize memory allocations: Avoid unnecessary allocations by reusing existing objects
or using buffers.
Use goroutines and channels efficiently: Leverage the power of concurrent programming,
but ensure proper synchronization to avoid race conditions.
Optimize loops and conditionals: Reduce the number of iterations by simplifying logic or
using more efficient algorithms.
Profile your code: Use Go's built-in profiling tools to identify bottlenecks and hotspots in
your code.
6. What is the role of the "init" function in Go?
The "init" function is a special function in Go that is used to initialize global variables or
perform any other setup tasks needed by a package before it is used. The init function is
called automatically when the package is first initialized. Its execution order within a package
is not guaranteed.
Multiple init functions can be defined within a single package and even within a single file.
This allows for modular and flexible initialization of package-level resources. Overall, the
init function plays a crucial role in ensuring that packages are correctly initialized and ready
to use when they are called.
7. What are dynamic and static types of declaration of a variable in Go?
The compiler must interpret the type of variable in a dynamic type variable declaration based
on the value provided to it. The compiler does not consider it necessary for a variable to be
typed statically.
Static type variable declaration assures the compiler that there is only one variable with the
provided type and name, allowing the compiler to continue compiling without having all of
the variable's details. A variable declaration only has meaning when the program is being
compiled; the compiler requires genuine variable declaration when the program is being
linked.
8. What is the syntax for declaring a variable in Go?
In Go, variables can be declared using the var keyword followed by the variable name, type,
and optional initial value. For example:
var age int = 29
Go also allows short variable declaration using the := operator, which automatically infers the
variable type based on the assigned value. For example:
age := 29
In this case, the type of the variable is inferred from the value assigned to it.
9. What are Golang packages?
This is a common Golang interview question. Go Packages (abbreviated pkg) are simply
directories in the Go workspace that contain Go source files or other Go packages. Every
piece of code created in the source files, from variables to functions, is then placed in a linked
package. Every source file should be associated with a package.
10. What are the different types of data types in Go?
To create a constant in Go, you can use the const keyword, followed by the name of the
constant and its value. The value must be a compile-time constant such as a string, number,
or boolean. Here's an example:
const Pi = 3.14159
After defining a constant, you can use it in your code throughout the program. Note that
constants cannot be reassigned or modified during the execution of the program.
Creating constants allows you to give meaningful names to important values that remain
constant throughout your Go program.
12.What data types does Golang use?
This is a common golang interview question. Golang uses the following types:
Slice
Struct
Pointer
Function
Method
Boolean
Numeric
String
Array
Interface
Map
Channel
13. Distinguish unbuffered from buffered channels.
This is a popular Golang interview question. The sender will block on an unbuffered channel
until the receiver receives data from the channel, and the receiver will block on the channel
until the sender puts data into the channel.
The sender of the buffered channel will block when there is no empty slot on the channel,
however, the receiver will block on the channel when it is empty, as opposed to the
unbuffered equivalent.
14. Explain string literals.
A string literal is a character-concatenated string constant. Raw string literals and interpreted
string literals are the two types of string literals. Raw string literals are enclosed in backticks
(foo) and contain uninterpreted UTF-8 characters. Interpreted string literals are strings that
are written within double quotes and can contain any character except newlines and
unfinished double-quotes.
15. What is a Goroutine and how do you stop it?
A Goroutine is a function or procedure that runs concurrently with other Goroutines on a dedicated
Goroutine thread. Goroutine threads are lighter than ordinary threads, and most Golang programs use
thousands of goroutines at the same time.
A Goroutine can be stopped by passing it a signal channel. Because Goroutines can only respond to
signals if they are taught to check, you must put checks at logical places, such as at the top of your for
a loop.
16. What is the syntax for creating a function in Go?
To create a function in Go, you need to use the keyword func, followed by the function name,
any parameter(s) enclosed in parentheses, and any return type(s) enclosed in parentheses. The
function body is enclosed in curly braces {}.
Here is an example function that takes two integers as input and returns their sum:
We declare a function called add that takes two parameters, x and y, and returns their sum as
an int.
17. How do you create a loop in Go?
The most commonly used loop is the for loop. It has three components: the initialization
statement, the condition statement, and the post statement.
In this example, the loop will iterate 10 times. You can modify the i, condition, and post
statement to customize the loop behavior.
18. What is the syntax for an if statement in Go?
For example,
This code block compares variables a and b and prints a message depending on their values.
The condition is evaluated, and if it's true, the code inside the curly braces is executed. If it's
false, the program skips to the else statement.
19. What are some benefits of using Go?
You can use the & symbol, followed by a variable to create a pointer in Go. This returns the
memory address of the variable. For example, if you have a variable num of type int, you can
create a pointer to num like this:
Here, ptr is a pointer to num. You can use the * symbol to access the value stored in the
memory address pointed by a pointer. For instance, *ptr will give you the value 42. Pointers
are useful for efficient memory sharing and passing references between functions.
21. What is the syntax for creating a struct in Go?
You need to define a blueprint for the struct, which may consist of fields of different data
types. The blueprint for the struct is defined using the 'type' keyword, followed by the name
you want to give the struct.
You then use the 'struct' keyword, followed by braces ('{}') where you list the fields, each
with a name and a data type separated by a comma.
For instance, the syntax for creating a struct named Person with the fields name, age, and job
of string, integer, and string data types, respectively, would be:
Creating an array in Go is simple. First, you need to declare the array by specifying its type
and size. You can do this by using the following syntax:
Replace size and datatype with the size and data type you want to use for your array. After
declaring the array, you can then initialize it by assigning values to each index. You can also
access and modify elements of the array using their index number.
Arrays in Go have fixed sizes, meaning you cannot add or remove elements once they are
declared.
23. How will you perform inheritance with Golang?
This is a trick golang interview question because Golang does not support classes, hence
there is no inheritance.
However, you may use composition to imitate inheritance behavior by leveraging an existing
struct object to establish the initial behavior of a new object. Once the new object is created,
the functionality of the original struct can be enhanced.
24. How do you create a slice in Go?
You first need to define a variable of type slice using the make() function. The make()
function takes two arguments: the first is the type of the slice you want to create (for
example, []string for a slice of strings) and the second is the length of the slice. The length of
the slice is not fixed and can be changed dynamically as elements are added or removed.
mySlice := make([]string, 5)
You can access and modify the elements in the slice using their index.
25. What is the difference between an array and a slice in Go?
In Go, an array is a fixed-length sequence of elements of the same type. Once an array is
defined, the length cannot be changed. On the other hand, a slice is a dynamically-sized,
flexible view of an underlying array. It is created with a variable length and can be resized.
Slices are typically used when you need to work with a portion of an array or when you want
to pass a subset of an array to a function. Slices provide more flexibility and are widely used
in Go for their convenience and efficiency in managing collections of data.
26. How do you create a map in Go?
You can use the make keyword, followed by the map keyword and the data types for the key
and value. The syntax would be make(map[keyType]valueType).
For example, to create a map of string keys and integer values, you would use
make(map[string]int). You can assign values to the map using the bracket notation such as
mapName[key] = value. To access values, simply use mapName[key].
Remember, maps in Go are unordered collections of key-value pairs, making them useful for
storing and retrieving data efficiently.
27. How do you iterate through a map in Go?
To iterate through a map in Go, you can use a for loop combined with the range keyword. For
example:
In this loop, key represents the key of each key-value pair in the map, and value represents
the corresponding value. You can perform any desired operation within the loop. The range
keyword automatically iterates over the map and gives you access to its keys and values.
28. What is a goroutine in Go?
Goroutines are more efficient in terms of memory usage and can be created and destroyed
quickly. They can communicate with each other through channels, which provide a safe way
to exchange data and synchronize their execution. This allows for efficient and scalable
concurrent programming in Go.
29. What are the looping constructs in Go?
There is only one looping construct in Go: the for loop. The for loop is made up of three parts
that are separated by semicolons:
Before the loop begins, the Init statement is run. It is frequently a variable declaration that
is only accessible within the scope of the for a loop.
Before each iteration, the condition statement is evaluated as a Boolean to determine if the
loop should continue.
At the end of each cycle, the post statement is executed.
30. What is a channel in Go?
Channels can be used to implement synchronization between goroutines and data sharing.
They provide a safe and efficient way to coordinate the flow of information, ensuring that
goroutines can send and receive data in a controlled and synchronized manner.
31. How do you create a channel in Go?
You can use the built-in make function with the chan keyword to create a channel in Go.
Here's an example:
ch := make(chan int)
In the above code, a channel called ch has been created that can transmit integers. This
channel can be used to send and receive data between goroutines.
By default, channels are unbuffered, meaning that the sender blocks until the receiver is
ready. You can also create buffered channels by providing a buffer capacity as a second
argument to the make function.
The close() function is used to close a channel in Go. The function is used to indicate that no
more values will be sent through the channel. Once a channel is closed, any subsequent
attempt to send data through it will result in a runtime panic. However, receiving from a
closed channel is still possible.
With the built-in v, ok := <-ch syntax, you can receive values from a closed channel. The ok
boolean flag will be set to false if the channel is closed. It's important to note that closed
channels should only be used for signaling and not for synchronization.
33. How do you range over a channel in Go?
To range over a channel in Go, a for loop with the range keyword can be used. This allows
you to iterate over all the values sent on the channel until it is closed. When using range, the
loop will continue until the channel is closed or until no more values are available.
The loop will print the values 0 to 4 as they are sent on the channel.
INTERMEDIATE GOLANG INTERVIEW QUESTIONS AND ANSWERS
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.
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?
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 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?
Hide Answer
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:
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:
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?
Hide Answer
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:
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.
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?
Hide Answer
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?
Hide Answer
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?
Hide Answer
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?
Hide Answer
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?
Hide Answer
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:
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?
Hide Answer
Compressing and decompressing data using the gzip algorithm entails the following steps:
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?
Hide Answer
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.
ADVANCED GOLANG INTERVIEW QUESTIONS AND ANSWERS
1.
Explain byte and rune types and how they are represented.
Hide Answer
A byte is a unit of data that typically consists of 8 bits and is used to represent a single
character, numeric value or instruction in computer systems. It's the smallest unit of data a
computer system can address and is commonly represented in hexadecimal notation.
A rune, on the other hand, is a Unicode character that represents a single code point or a
symbol in a script such as alphabet, digits, and punctuation. It can be as small as a byte or as
large as 4 bytes and is used to represent characters from different languages and scripts.
Both byte and rune types are fundamental to how computer systems store and process data,
and they are often used in programming languages to manipulate strings and characters.
2.
You have developed a Go program on Linux and want to compile it for both Windows and
Mac. Is it possible?
Hide Answer
Yes, it is possible to compile a Go program on Linux for both Windows and Mac. The Go
language provides a cross-compilation feature that allows you to build binaries for different
operating systems and architectures.
To compile your Go program for Windows, you can use the GOOS=windows environment
variable. For example, run GOOS=windows go build main.go to generate a Windows
executable.
Similarly, to compile for Mac, use GOOS=darwin. This flexibility makes it easy to target
multiple platforms from your Linux development environment. Just remember to test your
program on the target platform to ensure compatibility.
3.
How can you compile a Go program for Windows and Mac?
Hide Answer
To compile a Go program for Windows and Mac, you'll need to cross-compile it from your
development environment. You can use the GOOS and GOARCH environment variables to
specify the target operating system and architecture. For Windows, set GOOS to "windows"
and for Mac, set it to "darwin." Use "amd64" as the architecture for 64-bit systems.
For Windows:
For Mac:
In this example:
We start with the package declaration package main, indicating that this is the main
package of the program.
We import the "fmt" package with import "fmt". This package is essential for basic input
and output operations.
We define the main function using func main() { }, which serves as the entry point of the
program. All executable Go programs must have a main function.
Inside the main function, we use fmt.Println("Hello, World!") to print the "Hello, World!"
message to the console. We can add more code within the main function to perform
additional tasks as needed.
5.
What is the string data type in Golang, and how is it represented?
Hide Answer
In Golang, the string data type is used to represent a sequence of characters. It is declared
using double quotes (" ") or backticks ( ). Strings in Golang are immutable, meaning once
assigned, their values cannot be changed.
Golang represents strings as a sequence of bytes using UTF-8 encoding. This enables support
for a wide range of characters from different languages. The length of a string is calculated
based on the number of bytes it occupies.
String literals in Golang can also include escape sequences, such as "\n" for a newline
character or "\t" for a tab character, allowing for more flexible string manipulation and
formatting.
6.
How can you format the Go source code in an idiomatic way?
Hide Answer
There are several best practices to format Go source code idiomatically. They ensure that
code is more maintainable and readable.
Use the gofmt command to automatically format Go code according to the language
specification.
Keep lines short, preferably less than 80 characters. This makes the code easier to read and
review.
Use braces (curly brackets) on a new line to define control structures.
Use descriptive names for variables, constants, and functions in a concise and readable
manner.
7.
Can you change a specific character in a string?
Hide Answer
Yes, you can change a specific character in a string by determining its position and assigning
a new value to that position.
For example, in Python you can use indexing to access individual characters in a string. The
index starts at 0 for the first character, 1 for the second character, and so on. Once you have
determined the position of the character you want to change, you can reassign it a new value
using either slicing or concatenation.
However, it's important to note that strings are immutable, meaning you cannot change them
in-place, but rather, you have to create a new string with the specific changes you want.
8.
How can you concatenate string values? What happens when concatenating strings?
Hide Answer
Concatenating string values is simply the process of linking two or more strings together to
form one longer string. To concatenate string values, you can use the "+" operator or the
string interpolation feature available in some programming languages like Python, JavaScript,
Java, C#, etc.
When concatenating strings, the resulting string will consist of all the characters from the
original strings in the order they were concatenated. It’s important to note that string
concatenation is an operation that can impact the performance of your code, especially if you
are working with large strings or frequently joining strings in a loop.
9.
Give an example of an array and slice declaration.
Hide Answer
Array declaration:
var numbers [5]int // Declaring an array named numbers with a fixed size of 5 and integer
elements
Slice declaration:
var fruits []string // Declaring a slice named fruits without specifying its size
In Go, arrays have a fixed size while slices are dynamic and can grow or shrink. Arrays are
declared using square brackets with a specified size, while slices are declared without
specifying a size.
Slices are more commonly used in Go for their flexibility and ability to be changed during
runtime.
10.
Explain the backing array of a slice value.
Hide Answer
In Go, the backing array of a slice value is a hidden data structure that holds the elements of
the slice. When you create a slice from an existing array or slice, the slice value itself only
holds a pointer to the starting element of the slice in the backing array, along with the length
and capacity of the slice.
This allows efficient manipulation of the slice without needing to copy the underlying data. If
the slice is modified and exceeds its capacity, a new backing array may be allocated and the
elements will be copied to the new array. It's important to understand the concept of the
backing array to avoid unexpected behavior when working with slices in Go.
11.
Explain the Golang map type and its advantages.
Hide Answer
Golang's map type is a powerful data structure that allows you to store key-value pairs. It is
similar to dictionaries in other programming languages. The key advantage of using a map in
Golang is its flexibility and efficiency.
With maps, you can easily retrieve values by using their corresponding keys, making it ideal
for scenarios where quick lookups are required. Maps also allow you to add, modify, and
delete key-value pairs dynamically.
Additionally, Golang's map type automatically handles resizing and hash collisions, ensuring
optimal performance. Overall, the map type is a versatile and efficient data structure that
simplifies working with key-value pairs.
12.
What is the recommended Golang package for basic operations on files? What other Golang
packages are used to work with files?
Hide Answer
The recommended Golang package for basic operations on files is the os package. It provides
functions like Create, Open, Read, Write, and Close to create, open, read from, write to, and
close files, respectively.
Apart from the os package, there are others that can be used to work with files:
The io/ioutil package provides higher-level file I/O functions like ReadFile, WriteFile, and
so on.
The path/filepath package is used to operate on file paths.
13.
Explain the object-oriented architecture of Golang.
Hide Answer
Go’s object-oriented architecture refers to the way in which the language supports the
principles of object-oriented programming. While Go does not have traditional classes and
inheritance like some other languages, it does have structures and methods that can be
defined on those structures.
This provides a way to encapsulate data and behavior within a single entity. By using structs
and methods, you can achieve similar benefits to object-oriented programming such as code
reusability, modularity, and encapsulation.
Go promotes a composition-based approach where objects are built by combining smaller
objects, rather than relying on inheritance hierarchies. This makes the code easier to manage
and understand.
14.
What is a struct type? Can you change the struct definition at runtime?
Hide Answer
A struct type is a user-defined composite data type in programming languages like Golang, C,
and C++. It allows you to combine different data types (integers, floats, or strings) into a
single entity.
Unlike some other data types, the struct definition cannot be changed at runtime. Once a
struct type is defined, its structure and fields remain the same throughout the program's
execution. If you need to modify the struct's definition, you would typically need to
recompile and run the program again.
However, you can create multiple instances of a struct and modify the values of their fields at
runtime, which provides flexibility and dynamic behavior.
15.
What are anonymous structs and anonymous struct fields? Give an example of such a struct
declaration.
Hide Answer
Anonymous structs in Go are structs without a specific name defined. They are used when
you want to create a struct type that is only used in one place in your code. Anonymous struct
fields are similar but are used to embed anonymous fields within a struct.
In this example, we create an anonymous struct with two fields, name and age. We then
declare and initialize a variable called person using the struct type. Since the struct is
anonymous, we define its fields inside the curly braces on the same line where it is declared.
16.
Explain the defer statement in Golang. Give an example of a deferred function’s call.
Hide Answer
In Golang, the defer statement is used to postpone the execution of a function until the
surrounding function completes. This is useful when you want to ensure that certain clean-up
actions or resource releases are performed before exiting a function.
Here’s an example:
In this program, we first declare a string variable named str and initialize it to the value
"Hello, world!". We then use the fmt.Printf function to print the address of str using the %p
format specifier. Next, we declare an integer variable called num, and then declare a pointer
named ptr to that integer variable using the & operator.
18.
What are the advantages of passing pointers to functions?
Hide Answer
Golang methods are functions associated with a specific type that allow you to define
behaviors and actions for that type. Methods can be defined for both user-defined types and
built-in types.
Value receiver methods: These operate on a copy of the value and do not modify the original
value.
Pointer receiver methods: These can modify the original value and are generally used when
there is a need to modify the underlying data.
Methods in Golang are defined using the syntax func (receiverType) methodName(). They
are a powerful way to organize and encapsulate behaviors within Golang code.
20.
Create a Go program that defines a named type and a method (receiver function) for that
type.
Hide Answer
To start, define a named type using the type keyword in Go. For example, you can create a
named type called Person that has two fields - name and age:
Once you have defined your named type, create a method (or receiver function) for that type
using the func keyword. For example, you can create a method called greet that takes a
Person as its receiver and prints out a personalized greeting like this:
With this code, you can create a new Person object, such as person := Person{"John", 30},
and then call the greet method for that object using the syntax person.greet(). The output
would be "Hello, my name is John and I am 30 years old".
21.
How can you ensure a Go channel never blocks while sending data to it?
Hide Answer
You can use a buffered channel to prevent a Go channel from blocking during a send
operation. You can specify the buffer size when creating the channel using the make function.
For example:
This allows the channel to hold up to 10 values before blocking. When the channel is full,
further send operations will block until there is space in the buffer. Using a buffered channel
can help prevent goroutines from blocking, which improves concurrency in Go programs.
22.
Explain why concurrency is not parallelism?
Hide Answer
Concurrency and parallelism are often used interchangeably, but they have distinct
differences. Concurrency refers to multiple tasks being executed simultaneously, while
parallelism involves splitting a task into smaller sub-tasks and running them simultaneously.
The difference lies in the nature of the tasks being executed. In concurrency, multiple tasks
may be executing at the same time but they may not necessarily be related to the same task.
In parallelism, the focus is on breaking down a single task into smaller sub-tasks.
Concurrency is not always parallelism because it is possible for multiple tasks to be executed
concurrently on a single processor without actually being parallel. In other words, parallelism
is a form of concurrency, but not all concurrency is parallelism.
23.
What is a data race?
Hide Answer
A data race occurs in multi-threaded programs when two or more threads access shared data
concurrently without proper synchronization. This can lead to unpredictable and erroneous
behavior as the order of execution and access to the shared data becomes non-deterministic.
Data races can result in incorrect calculations or data corruption, compromising the integrity
and correctness of the program. To mitigate data races, you can use techniques like locks,
mutexes, and atomic operations to enforce exclusive access to shared data.
Additionally, programming languages and tools often provide features and utilities to detect
and prevent data races during development and testing.
24.
How can you detect a data race in Go code?
Hide Answer
One way to detect a data race in Go code is to use the built-in data race detector. It can be
enabled with the -race flag when building or running the program.
In the context of Go, a channel is a powerful concurrency primitive that allows goroutines to
communicate and synchronize their work. Channels facilitate safe communication and data
sharing between goroutines, which helps in building concurrent and parallel programs.
Sending data to a channel: channelName <- data. This operation sends the specified data to
the channel.
Receiving data from a channel: data := <-channelName. This operation receives data from
the channel and assigns it to a variable.
Closing a channel: close(channelName). This operation closes the channel to indicate that
no more data will be sent.
Checking if a channel is closed: value, ok := <-channelName. This operation checks if the
channel is closed by reading from it. If the channel is closed, ok will be false.
26.
How can you ensure that a goroutine in Go receives data from a channel without blocking
indefinitely if there's no data available, and without terminating prematurely if the channel is
still producing data?
Hide Answer
You can achieve this by using a buffered channel with a suitable capacity. A buffered channel
allows sending data to it without blocking until the channel is full, and receiving data from it
without blocking until the channel is empty. This ensures goroutines can send and receive
data asynchronously without risking deadlock or premature termination.
For example, you can create a buffered channel with a capacity of 10 as follows:
Goroutines can send up to 10 values to this channel before blocking. They can also receive
from it without blocking until it's empty.
27.
Write a simple Golang program that uses a goroutine and a channel.
Hide Answer
In this program, we create a channel of type string using make(). We then launch a goroutine
using the go keyword and invoke sendMessage() function. Inside the sendMessage()
function, we sleep for 2 seconds and then send a message over the channel. In the main
routine, we wait to receive a message from the channel and print it to the console.
28.
Write a program to find the sum of all even numbers from 1 to 100.
Hide Answer
29.
Write a program to find the largest and smallest elements in an array.
Hide Answer
30.
Write a program to check if a number is prime.
Hide Answer
31.
Write a program to calculate the factorial of a number using recursion.
Hide Answer
32.
Write a program to count the number of words in a given string.
Hide Answer
The Split method separates a string into substrings based on a specified separator, which in
this case is a space character. However, it counts any sequence of characters separated by
spaces as a single word, which may include punctuation marks and other non-word
characters.
On the other hand, regular expressions allow us to define patterns that match only specific
types of characters or substrings. By using a regular expression that matches only individual
words (i.e., alphabetic characters without any separators or punctuation marks), we can get a
more accurate count of the number of words in the given text
33.
Write a program to generate random numbers within a specified range.
Hide Answer
34.
Write a program to implement a bubble sort algorithm.
Hide Answer
35.
Write a program to generate permutations of a given string.
Hide Answer
36.
Write a program to implement the Boyer-Moore string search algorithm.
Hide Answer
37.
Write a program to find the longest increasing subsequence in a given array.
Hide Answer
38.
Write a program to implement a binary tree and perform various operations.
Hide Answer
39.
Write a program to implement a stack using an array.
Hide Answer
40.
Write a program to implement a queue using a linked list.
Hide Answer
Go Variable Naming Rules
A variable can have a short name (like x and y) or a more descriptive name
(age, price, carname, etc.).
Here,
number - name of the variable
var - keyword used to declare variable
int - data type associated with the variable
Go Constants
The const keyword declares the variable as "constant", which means that it
is unchangeable and read-only.
Syntax
const CONSTNAME type = value
Example:
const PI = 3.14
Go Output Functions
Go has three functions to output text:
Print()
The Print() function prints its arguments with their default format.
var i,j string = "Hello","World"
fmt.Print(i)
fmt.Print(j)
If we want to print the arguments in new lines, we need to use \n.
var i,j string = "Hello","World"
fmt.Print(i, "\n")
fmt.Print(j, "\n")
It is also possible to only use one Print() for printing multiple variables.
fmt.Print(i, "\n",j)
Println()
a whitespace is added between the arguments, and a newline is added at
the end:
Printf()
The Printf() function first formats its argument based on the given
formatting verb and then prints them.
func main() {
var i string = "Hello"
var j int = 15
Go Data Types
1. Basic data types:
bool: represents a boolean value and is either true or false
var a bool = true // Boolean
var b int = 5 // Integer
var c float32 = 3.14 // Floating point number
var d string = "Hi!" // String
Numeric: represents integer types, floating point values, and complex
types
2. Aggregate Types
a. Arrays
b. Structures
3. Reference Types
c. Pointers
d. Slices
e. Maps
f. Functions
g. Channels
4. Interface Types
Go Print Statement
There are three functions to print output messages in Go programming.
fmt.Print() - function prints the content inside parentheses () .
Format Specifier
Data Type Format Specifier
integer %d
float %g
string %s
bool %t
Go Take Input
we use the scan() function to take input from the user.
Go String
The Go platform provides various libraries to manipulate strings.
unicode
regexp
strings
Creating String
// create string using var
var message1 = "Hello,"
Note − The string literal is immutable, so that once it is created a string literal
cannot be changed.
String Length
len(str) method returns the number of bytes contained in the string literal.
fmt.Println(len(greeting))
Concatenating String
The strings package includes a method join for concatenating multiple strings
strings.Join(sample, " ")
greetings := []string{"Hello","world!"}
fmt.Println(strings.Join(greetings, " "))
In Go, the strings package provides various methods that can be used to
perform different operations on strings.
Functions Descriptions
Go Constant
To declare a constant in Golang, we use the const keyword followed by an
identifier (constant name), type, and the constant value. The constant value
must be assigned during the declaration of the constant.
Syntax:
const constant_name type = constant_value
const constant_name = constant_value
Go Arrays
Arrays are used to store multiple values of the same type in a single variable,
instead of declaring separate variables for each value.
Syntax:
arr1 := [5]int{1:10,2:40}
[0 10 40 0 0]
fmt.Println(len(arr1))
fmt.Println(len(arr2))
// declare an array
var arrayOfIntegers[3] int
fmt.Println(arrayOfIntegers)
fmt.Println(arrayOfIntegers)
Go Slices
The length of a slice can grow and shrink as you see fit.
Slices are also used to store multiple values of the same type in a single
variable.
Syntax:
slice_name := []datatype{values}
numbers := []int{1, 2, 3, 4, 5}
In Go, there are two functions that can be used to return the length and
capacity of a slice:
len() function - returns the length of the slice (the number of elements in
the slice)
cap() function - returns the capacity of the slice (the number of elements
the slice can grow or shrink to)
Create a Slice From an Array
Syntax:
var myarray = [length]datatype{values} // An array
myslice := myarray[start:end] // A slice made from the array
Memory Efficiency
When using slices, Go loads all the underlying elements into the memory.
If the array is large and you need only a few elements, it is better to copy
those elements using the copy() function.
The copy() function creates a new underlying array with only the required
elements for the slice. This will reduce the memory used for the program.
Syntax:
copy(dest, src)
numbers := []int{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} // Original slice
// Create copy with only needed numbers
neededNumbers := numbers[:len(numbers)-10]
numbersCopy := make([]int, len(neededNumbers))
copy(numbersCopy, neededNumbers)
func main() {
// create two slices
primeNumbers := []int{2, 3, 5, 7}
numbers := []int{1, 2, 3}
// print numbers
fmt.Println("Numbers:", numbers)
}
Output
Numbers: [2 3 5]
Go Operators
Operators are used to perform operations on variables and values.
Although the + operator is often used to add together two values, it can also
be used to add together a variable and a value, or a variable and another
variable:
var (
sum1 = 100 + 50 // 150 (100 + 50)
sum2 = sum1 + 250 // 400 (150 + 250)
sum3 = sum2 + sum2 // 800 (400 + 400)
)
Arithmetic operators
Assignment operators
Comparison operators
Logical operators
Bitwise operators
List of Golang Miscellaneous Operators
Example
Operator Description
x:=5
Address Of (&) Returns the address of a variable. &x
Pointer to a
Returns the value of a pointer variable. *x
variable (*)
Receive (<-) This operator is used to receive a value from the channel. y := <-ch
Go Conditions
The brackets in the else statement should be like } else {:
Go Flow Control
Go switch Statement
Important Details:
a. The entry expression is optional in switch, the default value is True (if
nothing is mentioned).
b. There is no break statement in Golang's switch statement, the code
breaks by default after each case.
c. The programmer can explicitly use the break and fall through
statements for cases if required.
d. Multiple cases of the same case are separated using comma (,).
e. The default statement is also optional in case of switch.
Use the switch statement to select one of many code blocks to be executed.
The difference is that it only runs the matched case so it does not need
a break statement.
All the case values should have the same type as the switch expression.
Otherwise, the compiler will raise an error:
func main() {
a := 3
switch a {
case a:
fmt.Println("a is one")
case "b":
fmt.Println("a is b")
}
}
switch day {
case 1,3,5:
fmt.Println("Odd weekday")
case 2,4:
fmt.Println("Even weekday")
case 6,7:
fmt.Println("Weekend")
default:
fmt.Println("Invalid day of day number")
}
}
Go if else
The if statement may have an optional else block. The syntax of
the if..else statement is:
if test_condition {
// run code if test_condition is true
} else {
// run code if test_condition is false
}
Go while Loop
We use the while loop to execute a block of code until a certain condition is met.
Unlike other programming languages, Go doesn't have a dedicated keyword for a
while loop. However, we can use the for loop to perform the functionality of a while
loop.
Syntax of Go while loop:
for condition {
// code block
}
Go For Loops
The for loop is the only loop available in Go.
func main() {
for i:=0; i < 5; i++ {
fmt.Println(i)
}
}
i:=0; - Initialize the loop counter (i), and set the start value to 0
i < 5; - Continue the loop as long as i is less than 5
i++ - Increase the loop counter value by 1 for each iteration
Result:
0
1
2
4
Result:
0
1
2
Result:
0 apple
1 orange
2 banana
Tip: To only show the value or the index, you can omit the other output
using an underscore (_).
fruits := [3]string{"apple", "orange", "banana"}
for _, val := range fruits {
fmt.Printf("%v\n", val)
}
Go Functions
A function is a block of statements that can be used repeatedly in a program.
A function will not execute automatically when a page loads.
A function will be executed by a call to the function.
Create a function
Use the func keyword.
Specify a name for the function, followed by parentheses ().
Finally, add code that defines what the function should do, inside curly
braces {}.
func FunctionName() {
// code to be executed
}
Call a function
To call the function, just write its name followed by two parentheses ().
Tip: Give the function a name that reflects what the function does!
func main() {
familyName("Liam")
}
Return Values
If you want the function to return a value, you need to define the data type
of the return value (such as int, string, etc), and also use
the return keyword inside the function:
func myFunction(x int, y int) int {
return x + y
}
func main() {
fmt.Println(myFunction(1, 2))
}
func main() {
fmt.Println(myFunction(1, 2))
}
func main() {
fmt.Println(myFunction(5, "Hello"))
}
If we (for some reason) do not want to use some of the returned values, we
can add an underscore (_), to omit this value.
func main() {
_, b := myFunction(5, "Hello")
fmt.Println(b)
}
Anonymous Functions
A function without the function name is known as an anonymous function.
// function call
sum(5, 3)
Since we have assigned the anonymous function to the sum variable, we are
calling the function using the variable name.
Return Value From Anonymous Function
// anonymous function
var sum = func(n1, n2 int) int {
sum := n1 + n2
return sum
}
// function call
result := sum(5, 3)
Recursion Functions
Go accepts recursion functions. A function is recursive if it calls itself and
reaches a stop condition.
func main(){
testcount(1)
}
factorial_recursion()
func main() {
fmt.Println(factorial_recursion(4))
}
Result:
24
Go Struct
A struct is used to store variables of different data types.
To declare a structure in Go, use the type and struct keywords:
Syntax:
type struct_name struct {
member1 datatype;
member2 datatype;
member3 datatype;
...
}
Example:
type Person struct {
name string
age int
job string
salary int
}
func main() {
//create an instance of struct
var pers1 Person
// Pers1 specification
pers1.name = "Hege"
pers1.age = 45
pers1.job = "Teacher"
pers1.salary = 6000
// Access and print Pers1 info
fmt.Println("Name: ", pers1.name)
fmt.Println("Age: ", pers1.age)
fmt.Println("Job: ", pers1.job)
fmt.Println("Salary: ", pers1.salary)
package main
import "fmt"
func main() {
// declare a struct
type Rectangle struct {
length int
breadth int
}
Go Maps
Maps are used to store data values in key:value pairs.
Each element in a map is a key:value pair.
A map is an unordered and changeable collection that does not allow
duplicates.
The length of a map is the number of its elements. You can find it using
the len() function.
The default value of a map is nil.
Maps hold references to an underlying hash table.
Example:
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
b := map[string]int{"Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4}
fmt.Printf("a\t%v\n", a)
fmt.Printf("b\t%v\n", b)
fmt.Println(a == nil)
fmt.Println(b == nil)
}
Result:
false
true
fmt.Println(a)
fmt.Println(b)
b["year"] = "1970"
fmt.Println("After change to b:")
fmt.Println(a)
fmt.Println(b)
}
Result:
map[brand:Ford model:Mustang year:1964]
map[brand:Ford model:Mustang year:1964]
After change to b:
map[brand:Ford model:Mustang year:1970]
map[brand:Ford model:Mustang year:1970]
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
}
Go Interfaces
Go programming provides another data type called interfaces which represents
a set of method signatures. The struct data type implements these interfaces to
have method definitions for the method signature of the interfaces.
Implementation of a Go Interface
Well, to use an interface, we first need to implement it by a type (struct). To implement an
interface, a struct should provide implementations for all methods of an interface.
Go Error Handling
Go programming provides a pretty simple error handling framework with inbuilt
error interface type of the following declaration −
type error interface {
Error() string
}
func main() {
sayHello()
sayHello("Rahul")
sayHello("Mohit", "Rahul", "Rohit", "Johny")
}
// using Ellipsis
func sayHello(names ...string) {
for _, n := range names {
fmt.Printf("Hello %s\n", n)
}
}
3. Functions
Functions are the set of statements wrapped within a block, these are the
building blocks of a Golang program. The func keyword followed by the
function name is used to declare a function. In Golang, main() is a special
function because it gets called when a program is executed.
Syntax:
func function_name(argument list){
//statements
}
main() function syntax:
func main(){
//statements
}
4. Variables
5. Statements & Expressions
6. Comments
7. Whitespaces & Blank lines
Creating a binary executable file
If we want to create a binary executable file, we can use the following
command,
$ go built exhello.go
This command will create a binary executable file named "exhello" and it can
be executed from the terminal/prompt like this,
$ ./exhello
Golang Comments
Types of Go comments
There are two types of comments in Golang:
1. Golang Single Line Comment
The single-line comment is created by the double forward-slash ( //).
2. Golang Multi-line Comment
The multi-line comment is also known as Block Comments, it is started by
the /* and ends with the */. So, any piece of code or text enclosed with
the /* and */ is considered as multi-line commented.
Pointers in Golang
A pointer is a special kind of variable that is not only used to store the memory addresses of
other variables but also points where the memory is located and provides ways to find out
the value stored at that memory location. It is generally termed as a Special kind of Variable
because it is almost declared as a variable but with *(dereferencing operator).
Declaration and Initialization of Pointers
Before we start there are two important operators which we will use in pointers
i.e.
* Operator also termed as the dereferencing operator used to declare pointer
variable and access the value stored in the address.
& operator termed as address operator used to returns the address of a
variable or to access the address of a variable to a pointer.
func main() {
// taking a normal variable
var x int = 5748
// declaration of pointer
var p *int
// initialization of pointer
p = &x
Concurrency in Golang
Goroutines
Every concurrently executing activity in Go language is known as a Goroutines.
How to create a Goroutine?
You can create your own Goroutine simply by using go keyword as a prefixing to
the function or method call .
package main
import (
"fmt"
"time"
)
func main() {
// Calling Goroutine
go display("Welcome")
time.Sleep(1 * time.Second)
fmt.Println("GoodBye!! to Main function")
}
Output:
Welcome!! to Main function
Welcome!! to GeeksforGeeks
GoodBye!! to Main function
Multiple Goroutines
// Go program to illustrate Multiple Goroutines
package main
import (
"fmt"
"time"
)
// For goroutine 1
func Aname() {
arr1 := [4]string{"Rohit", "Suman", "Aman", "Ria"}
Channel in Golang
A channel is a medium through which a goroutine communicates with another
goroutine and this communication is lock-free. By default channel is
bidirectional, means the goroutines can send or receive data through the same
channel.
Creating a channel
A channel is created using chan keyword and it can only transfer data of the same type,
different types of data are not allowed to transport from the same channel.
Syntax:
var Channel_name chan Type
or
channel_name:= make(chan Type)
Receive Operation:
The receive operation is used to receive the data sent by the send operator.
element := <-Mychannel
The above statement indicates that the element receives data from the channel(Mychannel). If the
result of the received statement is not going to use is also a valid statement. You can also write a
receive statement as:
<-Mychannel
Example:
// Go program to illustrate send and receive operation
package main
import "fmt"
func main() {
fmt.Println("start Main method")
// Creating a channel
ch := make(chan int)
go myfunc(ch)
ch <- 23
fmt.Println("End Main method")
}
Output:
start Main method
257
End Main method
Closing a Channel
You can also close a channel with the help of close() function. This is an in-built function and sets a
flag which indicates that no more value will send to this channel.
Syntax:
close()
You can also close the channel using for range loop. Here, the receiver goroutine can check the
channel is open or close with the help of the given syntax:
ele, ok:= <- Mychannel
Here, if the value of ok is true which means the channel is open so, read operations can be
performed. And if the value of is false which means the channel is closed so, read operations are not
going to perform.
Example:
// Go program to illustrate how to close a channel using for range loop and
close function
package main
import "fmt"
// Function
func myfun(mychnl chan string) {
for v := 0; v < 4; v++ {
mychnl <- "GeeksforGeeks"
}
close(mychnl)
}
// Main function
func main() {
// Creating a channel
c := make(chan string)
// calling Goroutine
go myfun(c)
// When the value of ok is set to true means the channel is open and it
// can send or receive data When the value of ok is set to
// false means the channel is closed
for {
res, ok := <-c
if ok == false {
fmt.Println("Channel Close ", ok)
break
}
fmt.Println("Channel Open ", res, ok)
}
}
Output:
Channel Open GeeksforGeeks true
Channel Open GeeksforGeeks true
Channel Open GeeksforGeeks true
Channel Open GeeksforGeeks true
Channel Close false