基本的な質問
Go 言語の主な特徴を説明してください。
シンプルで効率的な構文を持つコンパイル型言語で、並行処理をサポートする goroutine やガベージコレクション機能を備えています。
Go のプロジェクトを初期化する方法を教えてください。
go mod init <module-name> を実行してモジュールを初期化します。
Go 言語の構造体(struct)の使い方を説明してください。
フィールドを持つデータ型を定義できます。
type Person struct {
Name string
Age int
}
func main() {
p := Person{Name: "John", Age: 30}
fmt.Println(p.Name, p.Age)
}
Go 言語の型システムはどのようなものですか?
静的型付けであり、型推論(型の明示を省略)もサポートしています。基本型、構造体、インターフェースなどがあります。
defer の用途と仕組みを説明してください。
関数の終了時に指定された処理を遅延実行します。
func main() {
defer fmt.Println("後処理")
fmt.Println("通常処理")
}
関数とメソッド
Go の関数の基本的な構文を説明してください。
関数は func キーワードで定義します。
func add(a int, b int) int {
return a + b
}
複数の戻り値を返す関数を作成する方法を説明してください。
関数から複数の値を返すことができます。
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
Go 言語のメソッドとは何ですか?
型に関連付けられた関数です。
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
メソッドのポインタレシーバーと値レシーバーの違いは何ですか?
ポインタレシーバーは元のデータを変更可能、値レシーバーはコピーを操作します。
可変長引数を使用する関数を作成する方法を説明してください。
... を使用して可変長引数を受け取ります。
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
並行処理
Go 言語の goroutine の仕組みを説明してください。
軽量スレッドで並行処理を実現します。
func sayHello() {
fmt.Println("Hello")
}
func main() {
go sayHello()
fmt.Println("World")
}
チャネル(channel)の用途と基本的な使い方を説明してください。
goroutine 間のデータ共有に使用します。
func main() {
ch := make(chan int)
go func() {
ch <- 42
}()
fmt.Println(<-ch)
}
バッファ付きチャネルとバッファなしチャネルの違いを説明してください。
バッファ付きチャネルは指定された容量まで非同期にデータを送受信できます。バッファなしチャネルは同期的に動作します。
select 文を使用する目的と例を挙げてください。
複数のチャネル操作を待ち受けるために使用します。
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() { ch1 <- "from ch1" }()
go func() { ch2 <- "from ch2" }()
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
sync.WaitGroup を使用する理由とその使い方を説明してください。
goroutine の完了を待つために使用します。
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Goroutine 完了")
}()
wg.Wait()
fmt.Println("全て完了")
}
エラーハンドリング
Go のエラーハンドリングの特徴を説明してください。
明示的にエラーを返し、呼び出し元でチェックします。
カスタムエラーを作成する方法を説明してください。
errors.New または fmt.Errorf を使用してエラーを生成します。
panic と recover の使用例を挙げてください。
異常状態を処理するために使用します。
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from", r)
}
}()
panic("Something went wrong")
}
Go の標準ライブラリで提供されるエラーパッケージをいくつか挙げてください。
errors パッケージ、fmt.Errorf 関数。
エラーハンドリングを行う上でのベストプラクティスを説明してください。
エラーを詳細に記述し、適切な場所でロギングや再スローを行う。
その他
Go のパッケージ管理について説明してください。
go mod コマンドを使用して依存関係を管理します。
Go のインターフェースの仕組みを説明してください。
メソッドの集合を定義し、具体的な実装は不要です。
type Shape interface {
Area() float64
}
Go のテストフレームワークについて説明してください。
標準ライブラリの testing パッケージを使用します。
Go 言語で HTTP サーバーを実装する方法を説明してください。
net/http パッケージを使用します。
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
Go 言語で JSON を扱う方法を説明してください。
encoding/json パッケージを使用してエンコード・デコードします。
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
jsonData := `{"name":"John", "age":30}`
var p Person
json.Unmarshal([]byte(jsonData), &p)
fmt.Println(p.Name, p.Age)
}