Day 1: 開発環境構築とHello World - 背景知識

プログラミングとは何か

コンピュータへの指示

プログラミングとは、コンピュータに「何をしてほしいか」を伝える作業です。

人間同士の会話では、「お茶を入れて」と頼めば相手は理解してくれます。しかし、コンピュータには以下のように詳しく伝える必要があります:

  • やかんに水を入れる
  • 火にかける
  • 沸騰するまで待つ
  • 茶葉を急須に入れる
  • お湯を注ぐ
  • 30秒待つ
  • 湯呑みに注ぐ
  • このような「手順」をコンピュータが理解できる言葉で書いたものが「プログラム」です。

    プログラミング言語の進化

    コンピュータが直接理解できるのは「0」と「1」の羅列(機械語)だけです。しかし、人間が0と1でプログラムを書くのは非常に困難です。

    そこで、人間が読み書きしやすい「プログラミング言語」が生まれました。Go、Python、Java、C++など、多くの言語があります。

    プログラミング言語の世代:

  • 第1世代(1940年代): 機械語 - 0と1の羅列
  • 第2世代(1950年代): アセンブリ言語 - 記号を使った低レベル言語
  • 第3世代(1960年代〜): C、Java、Python - 人間が読める高レベル言語
  • 第4世代(現代): Go、Rust、Swift - モダンで安全性重視の言語
  • ---

    Go言語について

    なぜGoなのか

    Go(別名:Golang)は2009年にGoogleで開発されたプログラミング言語です。

    特徴:

    特徴 説明
    シンプル 覚えることが少なく、学習しやすい
    速い コンパイル言語で実行速度が速い
    安全 メモリ管理が自動で、エラーが起きにくい
    並行処理 複数の処理を同時に行いやすい
    実用的 Google、メルカリ、LINEなど多くの企業で使用

    Goの歴史と設計思想

    開発の経緯:

  • 2007年: Google社内で開発開始(Robert Griesemer、Rob Pike、Ken Thompson)
- 当時Googleでは、C++のコンパイル時間が非常に長く、開発生産性が問題になっていた - 複雑化したプログラミング言語への不満が高まっていた
  • 2009年11月10日: オープンソースとして公開
  • 2012年3月28日: Go 1.0リリース(後方互換性の保証開始)
  • 2015年: Go 1.5でGoコンパイラ自体がGoで書き直される(セルフホスティング達成)
  • 現在: 世界中で広く使われるモダン言語に
  • 設計哲学:

  • シンプルさ: 「少ないことは多いこと(Less is more)」
  • 実用性: 理論より実践を重視
  • 並行処理: マルチコアCPU時代に対応
  • 高速コンパイル: 開発者の待ち時間を最小化
  • 明確さ: 暗黙的な動作を避け、明示的に書く

Go言語の生みの親たち

Rob Pike(ロブ・パイク):

  • UNIX、Plan 9、UTF-8の開発に関わった伝説的プログラマー
  • 「シンプルさ」を徹底的に追求

Ken Thompson(ケン・トンプソン):

  • UNIXとCの共同開発者
  • チューリング賞受賞者
  • 実行効率を重視した設計

Robert Griesemer(ロバート・グリースマー):

  • JavaのHotSpot JVMやV8 JavaScriptエンジンに貢献
  • 型システムと並行処理の専門家

---

実世界での活用事例

1. Google(開発元)

使用例:

  • YouTube: 動画配信基盤の一部
  • Kubernetes: コンテナオーケストレーションシステム(全体がGoで書かれている)
  • Google Cloud Platform: 多くのバックエンドサービス

なぜGoを選んだのか:

  • 大規模システムでの高いパフォーマンス
  • 並行処理による効率的なリソース利用
  • シンプルな構文による保守性の向上

2. Docker(コンテナ技術)

使用例:

  • Docker本体が全てGoで実装
  • 2013年の登場以来、DevOpsの標準ツールに

Goを選んだ理由:

  • クロスプラットフォーム対応(Windows、Mac、Linux)
  • 単一バイナリで配布可能
  • システムプログラミングに適した性能

3. Uber(ライドシェア)

使用例:

  • マイクロサービスアーキテクチャの基盤
  • リアルタイム位置情報処理
  • 高負荷トラフィック処理

導入効果:

  • サービスの応答時間が大幅に改善
  • メモリ使用量の削減
  • 開発者の生産性向上

4. Netflix(動画ストリーミング)

使用例:

  • Rend: 分散キャッシュシステム
  • インフラストラクチャツール

選定理由:

  • 1億人以上の同時接続を支える性能
  • 障害時の自動復旧機能
  • 運用コストの削減

5. メルカリ(日本)

使用例:

  • マイクロサービス基盤
  • API Gateway
  • データ処理パイプライン

導入背景:

  • 急成長するトラフィックへの対応
  • グローバル展開を見据えた技術選定
  • エンジニアの採用しやすさ
  • 6. その他の著名企業

  • Dropbox: データ同期エンジン
  • Twitch: チャットシステム
  • Cloudflare: CDNとセキュリティサービス
  • BBC: ニュース配信システム
  • Medium: ブログプラットフォーム

---

Go言語エンジニアの市場価値

年収データ(2024年現在)

日本国内:

  • ジュニアレベル(1-3年): 450万円〜650万円
  • ミドルレベル(3-5年): 650万円〜900万円
  • シニアレベル(5年以上): 900万円〜1,500万円
  • テックリード/アーキテクト: 1,200万円〜2,000万円以上

海外(主に米国):

  • ジュニア: $80,000〜$120,000
  • ミッド: $120,000〜$180,000
  • シニア: $180,000〜$250,000
  • スタッフエンジニア: $250,000〜$400,000以上

求人需要トレンド

Stack Overflow Developer Survey 2024:

  • 最も需要が高い言語: 5位
  • 最も愛されている言語: 4位
  • 最も学びたい言語: 6位

求人数の推移:

  • 2020年比で約3倍の求人増加
  • クラウドネイティブ開発案件が急増
  • DevOps/SREポジションでの需要が特に高い
  • キャリアパス

    典型的なキャリアパス:

  • バックエンドエンジニアシニアバックエンドエンジニア
- WebサービスのAPI開発 - データベース設計と最適化

  • クラウドエンジニアクラウドアーキテクト
- Kubernetes環境の構築・運用 - マイクロサービス設計

  • SREエンジニアリードSRE
- インフラ自動化 - 監視・アラート設計

  • フルスタックエンジニアテックリード
- フロントエンドとバックエンドの両方 - チーム全体の技術選定

スキルの組み合わせで市場価値UP:

  • Go + Kubernetes: クラウドネイティブ開発
  • Go + Docker: コンテナ化・DevOps
  • Go + gRPC: マイクロサービス通信
  • Go + AWS/GCP/Azure: クラウドインフラ
  • ---

    開発環境の構成要素

    1. Go言語処理系

    プログラムを実行するために必要なソフトウェアです。

    ┌─────────────────────────────────────────┐
    │          あなたが書くコード               │
    │          (main.go)                       │
    └─────────────────┬───────────────────────┘
                      ↓ コンパイル
    ┌─────────────────────────────────────────┐
    │          実行可能ファイル                  │
    │          (main または main.exe)          │
    └─────────────────┬───────────────────────┘
                      ↓ 実行
    ┌─────────────────────────────────────────┐
    │          出力結果                         │
    │          "Hello, World!"                 │
    └─────────────────────────────────────────┘
    

    コンパイルとインタプリタの違い:

    方式 言語例 特徴 速度
    コンパイル Go、C、Rust 実行前に機械語に変換 速い
    インタプリタ Python、Ruby 実行時に逐次解釈 遅い
    JIT Java、JavaScript 実行時にコンパイル 中間

    2. テキストエディタ

    プログラムを書くためのソフトウェアです。

    Visual Studio Code(VS Code)が推奨される理由:

  • 無料で使える
  • Go言語の拡張機能が充実
  • エラーの指摘、コード補完などが便利
  • 世界中の開発者が使用(シェア率70%以上)

必須のVS Code拡張機能:

  • Go(公式): Goの開発支援
  • Error Lens: エラーをインラインで表示
  • GitLens: Git履歴の可視化
  • Better Comments: コメントの色分け

代替エディタ:

  • GoLand: JetBrains製の有料IDE(機能豊富)
  • Vim/Neovim: 軽量・高速なテキストエディタ
  • Sublime Text: シンプルで高速
  • 3. ターミナル(コマンドライン)

    コマンドを入力してプログラムを実行する画面です。

    $ go run main.go    # プログラムを実行
    Hello, World!       # 出力結果
    

    よく使うGoコマンド:

    コマンド 用途
    `go run` コンパイル&実行
    `go build` 実行ファイルを生成
    `go test` テストを実行
    `go fmt` コードを整形
    `go mod` 依存関係管理

    ---

    Goプログラムの基本構造

    必須要素

    すべてのGoプログラムには以下の要素が必要です:

    package main        // 1. パッケージ宣言
    
    import "fmt"        // 2. インポート
    
    func main() {       // 3. main関数
        // ここに処理を書く
    }
    

    各要素の説明

    1. パッケージ宣言(package)

    package main
    

  • すべてのGoファイルはpackageで始まる
  • mainパッケージ = 「このプログラムを実行できる」という意味
  • ライブラリを作る場合は別の名前を使う

パッケージの役割:

  • コードを論理的な単位に分割
  • 名前空間の提供(名前の衝突を防ぐ)
  • 再利用可能なコードの作成
  • 2. インポート(import)

    import "fmt"
    

  • 外部の「道具箱」を借りてくる宣言
  • fmtは「フォーマット」の略で、文字を表示する機能を持つ
  • 複数インポートする場合:

import (
    "fmt"
    "math"
    "strings"
)

標準ライブラリの主要パッケージ:

  • fmt: フォーマット付き入出力
  • os: オペレーティングシステム機能
  • io: 入出力プリミティブ
  • net/http: HTTPクライアント・サーバー
  • encoding/json: JSON処理
  • time: 時刻・日付処理
  • 3. main関数

    func main() {
        // 処理
    }
    

  • func = function(関数)の略
  • main() = プログラムの「入口」(エントリーポイント)
  • { } = 処理の範囲を示す(ブロック)

main関数の特徴:

  • プログラム実行時に自動的に呼ばれる
  • 引数を取らない
  • 戻り値を返さない
  • mainパッケージに必ず1つ存在する必要がある
  • ---

    fmt パッケージ

    主な関数

    関数 説明
    `Println` 文字列を表示して改行 `fmt.Println("Hello")`
    `Print` 文字列を表示(改行なし) `fmt.Print("Hello")`
    `Printf` フォーマット付きで表示 `fmt.Printf("Age: %d", 25)`
    `Sprintf` フォーマットした文字列を返す `s := fmt.Sprintf("Age: %d", 25)`
    `Scan` 標準入力から読み込む `fmt.Scan(&name)`

    Println vs Print

    // Println(改行あり)
    fmt.Println("りんご")
    fmt.Println("みかん")
    // 出力:
    // りんご
    // みかん
    
    // Print(改行なし)
    fmt.Print("りんご")
    fmt.Print("みかん")
    // 出力:
    // りんごみかん
    

    Printfのフォーマット指定子

    指定子 説明
    `%d` int 10進数
    `%f` float 浮動小数点数
    `%s` string 文字列
    `%t` bool 真偽値
    `%v` any デフォルトフォーマット
    `%T` any 型を表示
    `%p` pointer ポインタアドレス

    ---

    文字列(String)

    基本ルール

  • 文字列は必ず""(ダブルクォート)で囲む
  • ''(シングルクォート)は使えない(runeリテラル用)
  • 日本語も使用可能(UTF-8エンコーディング)

"Hello, World!"     // OK
"こんにちは"         // OK(日本語)
'Hello'             // NG(シングルクォートは文字列に使えない)
Hello               // NG(クォートなしは変数名と解釈される)

文字列の連結

+演算子で文字列を連結できます:

"Hello, " + "World!"  // → "Hello, World!"

エスケープシーケンス

特殊な文字を表現する方法:

シーケンス 意味
`\n` 改行
`\t` タブ
`\"` ダブルクォート
`\\` バックスラッシュ

fmt.Println("1行目\n2行目")  // 改行
fmt.Println("名前\t年齢")     // タブ

---

開発手法とベストプラクティス

Test-Driven Development (TDD)

TDDの3ステップ:

  • Red: 失敗するテストを書く
  • Green: テストが通る最小限のコードを書く
  • Refactor: コードを改善する

初心者向けTDD:

// main_test.go
package main

import "testing"

func TestHello(t *testing.T) {
    result := "Hello, World!"
    expected := "Hello, World!"
    if result != expected {
        t.Errorf("got %s, want %s", result, expected)
    }
}

Gitワークフロー

基本的なGitコマンド:

git init              # リポジトリ初期化
git add .             # 変更をステージング
git commit -m "メッセージ"  # コミット
git status            # 状態確認
git log               # 履歴表示

良いコミットメッセージの書き方:

  • 1行目: 何をしたか(50文字以内)
  • 2行目: 空行
  • 3行目以降: なぜそうしたか(詳細)

Add hello world program

初めてのGoプログラムとして、
標準的なHello Worldを実装

コードレビューの観点

チェックポイント:

  • 動作確認: プログラムが正しく動くか
  • 可読性: 他の人が読みやすいか
  • 保守性: 後で変更しやすいか
  • 効率性: 無駄な処理がないか

デバッグ戦略

段階的デバッグ:

  • エラーメッセージを読む: 何が問題か理解する
  • print文を追加: 変数の値を確認する
  • コードを分割: 問題箇所を特定する
  • 最小再現: 問題を単純化する

デバッグ例:

func main() {
    name := "太郎"
    fmt.Printf("DEBUG: name = %s\n", name)  // デバッグ出力
    fmt.Println("こんにちは、" + name + "さん")
}

---

ソフトスキル:エンジニアとしての成長

質問の仕方

良い質問:

  • 何をしようとしているか説明
  • 何が期待される動作か説明
  • 実際に何が起きたか説明
  • エラーメッセージを共有
  • 試したことを共有

例:

【質問】Hello Worldが表示されません

【やりたいこと】
"Hello, World!"という文字列を画面に表示したい

【期待される動作】
Hello, World!と表示される

【実際の動作】
エラー: undefined: fmt.Printl

【試したこと】
1. go runコマンドで実行
2. スペルを確認(Printlと書いている)

【環境】
- Go version: 1.21
- OS: macOS

チーム開発とコミュニケーション

効果的なコミュニケーション:

  • 明確に: 曖昧な表現を避ける
  • 簡潔に: 要点を絞る
  • 具体的に: 例を示す
  • 建設的に: 解決策を提案する

ペアプログラミング:

  • ドライバー: コードを書く人
  • ナビゲーター: レビューする人
  • 定期的に役割を交代
  • 学習効果が高い

学習戦略

効果的な学習方法:

  • アクティブラーニング: 読むだけでなく書く
  • 反復練習: 同じコードを何度も書く
  • プロジェクトベース: 実際のものを作る
  • 教える: 他人に説明することで理解が深まる

プログラミング上達の段階:

  • 模倣: サンプルコードを写経
  • 理解: なぜそう書くか理解
  • 応用: 少し変更してみる
  • 創造: ゼロから書く

---

本番環境への考慮事項

セキュリティ

基本原則:

  • 入力検証: ユーザー入力を信頼しない
  • エラー処理: エラーを適切に処理
  • 最小権限: 必要最小限の権限で実行
  • ログ記録: 重要な操作を記録

避けるべきこと:

  • パスワードをコードに直接書く
  • エラーメッセージで内部情報を露出
  • 権限チェックを省略

パフォーマンス

最適化の優先順位:

  • まず動かす: 正しく動くコードを書く
  • 測定する: ボトルネックを特定
  • 最適化: 必要な部分だけ改善

Goのパフォーマンス特性:

  • 静的型付けによる高速実行
  • ガベージコレクションによるメモリ管理
  • ゴルーチンによる並行処理

スケーラビリティ

スケーラブルな設計:

  • ステートレス: 状態を持たない設計
  • 疎結合: モジュール間の依存を減らす
  • 並行処理: ゴルーチンを活用

---

よくあるエラーと対処法

エラーメッセージの読み方

./main.go:6:5: undefined: fmt.Printl

この形式の意味:

  • ./main.go = エラーがあるファイル
  • 6:5 = 6行目の5文字目
  • undefined: fmt.Printl = fmt.Printlは定義されていない
  • 代表的なエラー

    エラー 原因 解決方法
    `undefined` スペルミス、または未定義 正しいスペルを確認
    `syntax error` 文法エラー `{ }` や `""` の対応を確認
    `imported and not used` importしたのに使っていない 不要なimportを削除
    `declared and not used` 変数を宣言したのに使っていない 変数を使用するか削除

    ---

    インストール手順の詳細

    macOS

    # Homebrewがない場合は先にインストール
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
    # Goのインストール
    brew install go
    
    # 確認
    go version
    
    # パスの設定(.zshrcまたは.bashrc)
    export PATH=$PATH:/usr/local/go/bin
    export GOPATH=$HOME/go
    export PATH=$PATH:$GOPATH/bin
    

    Windows

  • 公式サイトからインストーラーをダウンロード
  • ダウンロードした.msiファイルを実行
  • 指示に従ってインストール
  • コマンドプロンプトでgo versionを実行して確認

環境変数の確認:

echo %GOPATH%
echo %GOROOT%

Linux(Ubuntu/Debian)

sudo apt update
sudo apt install golang-go

# または、最新版を直接インストール
wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz

# パスの設定(.bashrc)
export PATH=$PATH:/usr/local/go/bin

# 確認
go version

---

設計原則の基礎

KISS(Keep It Simple, Stupid)

シンプルに保つ:

// 複雑(避けるべき)
func isEven(n int) bool {
    if n % 2 == 0 {
        return true
    } else {
        return false
    }
}

// シンプル(推奨)
func isEven(n int) bool {
    return n % 2 == 0
}

DRY(Don't Repeat Yourself)

繰り返しを避ける:

// 悪い例
fmt.Println("こんにちは、太郎さん")
fmt.Println("こんにちは、花子さん")
fmt.Println("こんにちは、次郎さん")

// 良い例(後の学習で理解)
names := []string{"太郎", "花子", "次郎"}
for _, name := range names {
    fmt.Printf("こんにちは、%sさん\n", name)
}

---

参考資料

公式リソース:

学習サイト:

コミュニティ:

書籍:

  • 「プログラミング言語Go」(通称:ゴーファーの本)
  • 「Go言語による並行処理」
  • 「スターティングGo言語」