Go, or Golang, is an open-source programming language developed by Google. It is statically typed, compiled, and designed for building scalable and high-performance applications.
Goroutines are lightweight threads managed by the Go runtime. They are functions or methods that run concurrently with other functions or methods.
Use the go keyword before a function call:
go myFunction()
Channels are a way for Goroutines to communicate with each other and synchronize their execution. They allow sending and receiving values.
ch := make(chan int)
A buffered channel has a specified capacity and allows sending of values until the buffer is full. It doesn't require a receiver to be ready to receive.
Use the close() function:
close(ch)
A struct is a user-defined type that allows grouping fields of different data types into a single entity.
type Person struct { Name string Age int }
An interface in Go is a type that specifies a set of method signatures. It allows polymorphism by defining behavior.
A type implements an interface by implementing all its methods:
type Animal interface { Speak() string } type Dog struct{} func (d Dog) Speak() string { return "Woof!" }
defer is used to postpone the execution of a function until the surrounding function returns.
Deferred functions are executed in LIFO (Last In, First Out) order:
defer fmt.Println("world") fmt.Println("hello") // Output: hello world
A pointer holds the memory address of a value. It is used to pass references instead of copying values.
var p *int p = &x
A slice is a dynamically-sized array that provides a more flexible way to work with sequences of elements.
s := make([]int, 0)
A map is a collection of key-value pairs.
m := make(map[string]int)
select allows a Goroutine to wait on multiple communication operations.
select { case msg := <-ch: fmt.Println(msg) default: fmt.Println("No message received") }
A nil channel blocks both sending and receiving operations.
init is a special function that initializes package-level variables. It is executed before main.
Yes, but they will be executed in the order they appear.
An empty struct consumes zero bytes of storage.
By returning an error type and checking it using:
if err != nil { return err }
Type assertion is used to extract the underlying value of an interface:
value, ok := x.(string)
go fmt formats Go source code according to the standard style.
go mod manages module dependencies in Go projects.
go mod init module-name
A package is a way to group related Go files together.
import "fmt"
panic is used to terminate the program immediately when an error occurs.
recover is used to regain control after a panic.
It is used inside a deferred function:
defer func() { if r := recover(); r != nil { fmt.Println("Recovered:", r) } }()
Constants are immutable values declared using the const keyword.
const Pi = 3.14
iota is a constant generator that increments by 1 automatically.
go test is used to run unit tests written in Go.
Test functions must start with Test:
func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("expected 5, got %d", result) } }
Benchmarking is used to measure the performance of a function using go test.
Benchmark functions must start with Benchmark:
func BenchmarkAdd(b *testing.B) { for i := 0; i < b.N; i++ { Add(2, 3) } }
Build constraints are used to include or exclude files from the build process based on conditions.
Place the constraint in a comment at the top of the file:
// +build linux
Slices are built on top of arrays and provide a dynamic view over the array.
Go automatically manages memory using garbage collection, which frees up memory that is no longer in use.
The context package is used for managing deadlines, cancellation signals, and request-scoped values. It helps in controlling the flow of Goroutines and resources.
ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel()
sync.WaitGroup is used to wait for a collection of Goroutines to finish executing.
var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() // Do some work }() wg.Wait()
sync.Mutex provides a lock mechanism to protect shared resources from concurrent access.
var mu sync.Mutex mu.Lock() // critical section mu.Unlock()
select is used to handle multiple channel operations simultaneously, allowing a Goroutine to wait for multiple communication operations.
go generate is a command for generating code. It reads special comments within the source code to execute commands.
Method receivers specify the type the method is associated with, either by value or pointer:
func (p *Person) GetName() string { return p.Name }
Variadic functions accept a variable number of arguments:
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
A rune is an alias for int32 and represents a Unicode code point.
A select block without a default will block until one of its cases can proceed.
A ticker sends events at regular intervals:
ticker := time.NewTicker(time.Second)
Use the encoding/json package to marshal and unmarshal JSON:
jsonData, _ := json.Marshal(structure) json.Unmarshal(jsonData, &structure)
go vet examines Go source code and reports potential errors, focusing on issues that are not caught by the compiler.
An anonymous function is a function without a name and can be defined inline:
func() { fmt.Println("Hello") }()
time.Duration represents the elapsed time between two points and is a type of int64.
Use context.WithTimeout to set a timeout:
ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel()
A pipeline is a series of stages connected by channels, where each stage is a collection of Goroutines that receive values from upstream and send values downstream.
pkg is a directory used to place reusable packages. It is a common convention but not enforced by Go.
Use tools like dlv (Delve), print statements, or the log package.
type aliasing allows you to create a new name for an existing type:
type MyInt = int
slice1 := []int{1, 2} slice2 := []int{3, 4} copy(slice2, slice1) // [1, 2]
go doc is used to display documentation for a Go package, function, or variable.
Use recover to gracefully handle panics and log them for debugging:
defer func() { if r := recover(); r != nil { log.Println("Recovered from:", r) } }()
The unsafe package allows low-level memory manipulation. It is not recommended for regular use.
Use interfaces and constructor functions to pass dependencies, allowing easy mocking and testing.
type HttpClient interface{} func NewService(client HttpClient) *Service { return &Service{client: client} }
A Goroutine is a lightweight thread managed by the Go runtime. It differs from OS threads as it uses a smaller initial stack (2KB) and is multiplexed onto multiple OS threads. This makes Goroutines more efficient for handling concurrency.
The Go scheduler uses a work-stealing algorithm with M:N scheduling, where M represents OS threads and N represents Goroutines. It schedules Goroutines across available OS threads and CPUs, aiming to balance workload for optimal performance.
A memory leak occurs when allocated memory is not released. In Go, it can happen if Goroutines are not terminated or references to objects are kept unnecessarily. Use defer for cleanup and proper cancellation of Goroutines to prevent leaks.
Go uses a concurrent, mark-and-sweep garbage collector. It identifies reachable objects during the mark phase and collects the unreachable ones during the sweep phase, allowing other Goroutines to continue running during collection.
Race conditions occur when multiple Goroutines access a shared variable concurrently without proper synchronization. Use go run -race to detect race conditions in Go programs.
Struct tags provide metadata for struct fields, often used for JSON serialization:
type User struct { Name string `json:"name"` Age int `json:"age"` }
Create a custom error by implementing the error interface:
type MyError struct { Msg string } func (e *MyError) Error() string { return e.Msg }
A nil pointer dereference occurs when you attempt to access the value a nil pointer points to. Avoid this by checking for nil before using pointers.
sync.Pool is used for reusing objects and reducing GC pressure. It provides a way to cache reusable objects, unlike the GC which automatically frees unused memory.
Use channels to distribute tasks and manage worker Goroutines:
jobs := make(chan int, 100) for w := 1; w <= 3; w++ { go worker(w, jobs) }
The reflect package allows runtime inspection of types and values. It is used for dynamic operations like inspecting struct fields or methods.
Ensure Goroutines are terminated using context for cancellation or using timeouts with channels.
io.Reader has a Read method for reading data, while io.Writer has a Write method for writing data. They form the basis of Go's I/O abstractions.
A nil value interface is an interface with a nil underlying value. It can cause unexpected behavior when check nil, as an interface with a nil underlying value is not equal to nil.
type MyInterface interface{} var i MyInterface var m map[string]int i = m // This case, m is nil but i not nil
To handle above case, we could use interface assertion as following
if v, ok := i.(map[string]int); ok && v != nil { fmt.Printf("value not nil: %v\n", v) }
To prevent deadlocks, ensure that:
以上是常见的 Golang 面试问题的详细内容。更多信息请关注PHP中文网其他相关文章!