課題1: Go言語の理解と環境構築

課題概要

この課題では、Go言語の設計思想を深く理解し、実際の開発環境を構築します。なぜGoが現代のソフトウェア開発で重要なのか、他の言語とどう違うのかを実践を通じて学びます。

マンダトリー要件

要件1: Go開発環境の構築

公式サイト(https://go.dev/)から最新版のGoをインストールし、以下を確認してください:

# Goのバージョン確認
go version

# 出力例: go version go1.21.5 darwin/amd64

環境変数が正しく設定されていることを確認:

# GOPATH確認
go env GOPATH

# GOROOTの確認
go env GOROOT

要件2: Hello, World!プログラム

最初のGoプログラムを作成します。

ファイル: hello.go

package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!")
}

実行方法:

# 直接実行
go run hello.go

# ビルドして実行
go build hello.go
./hello

要件3: 設計哲学の分析レポート

以下の質問に対して、具体的なコード例を交えながら回答してください(各200-300文字):

Q1: Goに三項演算子(condition ? true_value : false_value)がない理由を、設計哲学の観点から説明してください。

Q2: Goのエラー処理(戻り値として返す方式)と、JavaやPythonの例外処理(try-catch)の違いについて、メリット・デメリットを説明してください。

Q3: 以下のC++コードをGoで書き換え、Goのどのような特徴が活かされているか説明してください:

#include <thread>
#include <iostream>

void task(int id) {
    std::cout << "Task " << id << std::endl;
}

int main() {
    std::thread t1(task, 1);
    std::thread t2(task, 2);
    t1.join();
    t2.join();
    return 0;
}

要件4: 比較プログラムの作成

C言語、Python、Goで同じ処理を実装し、コンパイル時間・実行時間・バイナリサイズを比較してください。

処理内容: 1から1000000までの数値の合計を計算する

C言語版 (sum.c):

#include <stdio.h>

int main() {
    long long sum = 0;
    for (int i = 1; i <= 1000000; i++) {
        sum += i;
    }
    printf("Sum: %lld\n", sum);
    return 0;
}

Python版 (sum.py):

sum_value = sum(range(1, 1000001))
print(f"Sum: {sum_value}")

Go版 (sum.go):

package main

import "fmt"

func main() {
    sum := 0
    for i := 1; i <= 1000000; i++ {
        sum += i
    }
    fmt.Printf("Sum: %d\n", sum)
}

測定方法:

# C言語
time gcc sum.c -o sum_c
time ./sum_c
ls -lh sum_c

# Python
time python3 sum.py

# Go
time go build sum.go
time ./sum
ls -lh sum

比較表を作成してください:

言語 コンパイル時間 実行時間 バイナリサイズ
C
Go
Python - (インタプリタ) -

期待される出力

Hello, World!の出力

Hello, Go!

合計計算の出力(全言語共通)

Sum: 500000500000

ボーナス課題

> ボーナス: これらはオプションです。マンダトリー部分が完了してから取り組んでください。

ボーナス1: 並行処理のパフォーマンス比較

goroutineの軽量性を実証するプログラムを作成してください。

要求:

  • 1000個のgoroutineを起動し、それぞれが1から1000までの数値の合計を計算
  • チャネルで結果を集約
  • 実行時間を測定
  • package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    func calculateSum(id int, wg *sync.WaitGroup, results chan<- int) {
        defer wg.Done()
        sum := 0
        for i := 1; i <= 1000; i++ {
            sum += i
        }
        results <- sum
    }
    
    func main() {
        start := time.Now()
    
        var wg sync.WaitGroup
        results := make(chan int, 1000)
    
        for i := 0; i < 1000; i++ {
            wg.Add(1)
            go calculateSum(i, &wg, results)
        }
    
        wg.Wait()
        close(results)
    
        total := 0
        for result := range results {
            total += result
        }
    
        elapsed := time.Since(start)
        fmt.Printf("Total: %d\n", total)
        fmt.Printf("Time: %v\n", elapsed)
    }
    

    同じ処理をPythonのスレッドで実装し、実行時間を比較してください。

    ボーナス2: クロスコンパイルの実践

    以下のプラットフォーム向けにビルドし、バイナリサイズを比較してください:

    # Linux (amd64)
    GOOS=linux GOARCH=amd64 go build -o hello_linux hello.go
    
    # Windows (amd64)
    GOOS=windows GOARCH=amd64 go build -o hello_windows.exe hello.go
    
    # macOS (arm64, Apple Silicon)
    GOOS=darwin GOARCH=arm64 go build -o hello_mac_arm hello.go
    
    # Raspberry Pi (ARM)
    GOOS=linux GOARCH=arm GOARM=7 go build -o hello_pi hello.go
    

    バイナリサイズ比較表:

    プラットフォーム バイナリサイズ 備考
    Linux (amd64)
    Windows (amd64)
    macOS (arm64)
    Raspberry Pi

    ボーナス3: Goのツールチェーン探索

    Goの標準ツールを使って、コード品質を向上させてください:

    # コードフォーマット
    go fmt hello.go
    
    # 静的解析
    go vet hello.go
    
    # コードのリント(golangci-lintをインストール)
    golangci-lint run hello.go
    
    # コードカバレッジ(テストコードがある場合)
    go test -cover
    
    # ベンチマーク
    go test -bench=.
    

    それぞれのツールの役割と出力結果を説明するレポートを作成してください。

    評価基準

    項目 配点 詳細
    環境構築 20点 Goが正しくインストールされ、動作確認ができている
    Hello, World! 10点 正しく動作するプログラムが書けている
    設計哲学分析 30点 各質問に対して具体的なコード例と共に説明されている
    比較プログラム 20点 3言語で実装し、測定結果が表にまとめられている
    **ボーナス1** 10点 goroutineの並行処理が正しく実装されている
    **ボーナス2** 5点 複数プラットフォーム向けにビルドできている
    **ボーナス3** 5点 Goツールチェーンの活用方法を理解している

    提出方法

    以下のファイルを提出してください:

    submission/
    ├── hello.go
    ├── sum.go
    ├── analysis.md          # 設計哲学の分析レポート
    ├── comparison.md        # 言語比較の結果
    └── bonus/              # ボーナス課題(オプション)
        ├── concurrent.go
        ├── cross_compile.md
        └── tools_report.md
    

    ヒント

  • 環境構築: go envコマンドで現在の設定を確認できます
  • エラー処理: Goのエラー処理パターンは明示的で追跡しやすい
  • 並行処理: sync.WaitGroupでgoroutineの完了を待つ
  • クロスコンパイル: GOOSとGOARCHの組み合わせはgo tool dist listで確認できる
  • ツール: go helpで利用可能なコマンドの一覧が表示されます
  • 学習リソース

  • Go公式サイト
  • A Tour of Go - インタラクティブなチュートリアル
  • Go by Example - 具体的なコード例
  • Effective Go - ベストプラクティス
  • Go FAQ - よくある質問