継続的デリバリー

f:id:kireifish:20121208044914j:plain

継続的デリバリー
信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化
Jez HumbleTwitter)、 David Farley 著、和智右桂、髙木正弘 訳 / amazon
 
現代では継続的にソフトウェアをリリースすることが必須になっています。
本書は、継続的なソフトウェアのデリバリーを実現するための
ビルド、デプロイ、テスト、リリースの自動化についての本格的な解説書です。

Jenkinsの概念について書かれた本。(ジュンク堂書店の小冊子「書標」4月号P.15より)
 
 
 
 
 
 
賛辞 - 川口耕介
本書は「俺たちはこういうふうにソフトウェアを開発・リリースしたいんだ」
という心の叫びが感じられます。
・・・対してJenkinsは、じゃあ実際にどうやってやるのよ、ということをメインに考えています。

第1部 基礎
 第01章 ソフトウェアデリバリーの問題 39
1.1 導入
1.2 リリースによくあるアンチパターン 40
1.3 もっとうまくできないだろうか? 47
1.4 どうすれば目標を達成できるだろうか? 48
1.5 どんな恩恵を受けられるのか? 54
1.6 リリース候補 60
1.7 ソフトウェアデリバリーの原則 62
1.8 まとめ

 第02章 構成管理 69
2.1 導入
2.2 バージョン管理を使う 70
2.3 依存関係の管理 76
2.4 ソフトウェア設定を管理する 78
2.5 環境を管理する 88
2.6 まとめ

3.1 導入
3.4 継続的インテグレーションソフトウェアを使用する 104
3.5 基本的なプラクティス 107
3.6 やったほうがいいプラクティス 113
3.7 分散したチーム 117
3.9 まとめ

 第04章 テスト戦略を実装する 127
4.1 導入
4.2 テストの種類 129
4.3 実際に起こり得る状況と戦略 137
4.4 プロセス 144
4.5 まとめ


第2部 デプロイメント パイプライン
 第05章 デプロイメント パイプラインの解剖学 151
5.1 導入
5.2 デプロイメントパイプラインとは何か? 153
5.3デプロイメントパイプラインのプラクティス 159
5.4 コミットステージ 166
5.5 自動受け入れテストという関門 169
5.6 後に続くテストステージ 173
5.7 リリースに備える 176
5.8デプロイメントパイプラインを実装する 180
5.9 メトリクス 186
5.10 まとめ

 第06章 ビルド・デプロイメントスクリプト 191
6.1 導入
6.2 ビルドツールの概要 192
6.3 ビルドスクリプトとデプロイメントパイプラインの原則とプラクティス 200
6.4 JVMを対象としたアプリケーションのためのプロジェクト構造 206
6.5 デプロイメントスクリプト 210
6.6 コツと裏技 214
6.7 まとめ

 第07章 コミットステージ 221
7.1 導入
7.2 コミットステの原則とプラクティス 222
7.3 コミットステージの結果 227
7.4 コミットテストスイートの原則とプラクティス 230
7.5 まとめ

 第08章 自動受け入れテスト 241
8.1 導入
8.2 なぜ自動受け入れテストが欠かせないのか? 242
8.3 受け入れテストを作成する 247
8.4 アプリケーションドライバレイヤ 253
8.5 受け入れテストを実装する 259
8.6 受け入れテストステージ 269
8.7 受け入れテストのパフォーマンス 275
8.8 まとめ


 第09章 非機能要件をテストする 281
9.1 導入
9.2 非機能用件を管理する 282
9.3 キャパシティを確保するためのプログラミング 284
9.4 キャパシティを計測する 287
9.5キャパシティテスト環境 291
9.6キャパシティテストを自動化する 294
9.7キャパシティテストをデプロイメントパイプラインに追加する 302
9.8キャパシティテストシステムのもうひとつの利点 304
9.9 まとめ

 第10章 アプリケーションをデプロイ・リリースする 307
10.1 導入
10.2 リリース戦略を作成する 308
10.3 アプリケーションをデプロイする 310
10.4 デプロイメントのロールバック、そしてゼロダウンタイム・リリース 317
10.5 緊急修正 324
10.6 継続的デプロイメント 325
10.7 ヒントと裏技 329
10.8 まとめ


第3部 デリバリー エコシステム
 第11章 基盤と環境を管理する 337
11.1 導入
11.2 運用チームのニーズを理解する 339
11.3 基盤をモデリングし、管理する 343
11.4 サーバーのプロビジョニングおよび設定を管理する 348
11.5 ミドルウェアの構成を管理する 356
11.6 基盤サービスを管理する 361
11.7 仮想化 364
11.9 基盤やアプリケーションを監視する 378
11.10 まとめ

 第12章 データと管理する 387
12.1 導入
12.2 データベースのスクリプト処理 388
12.3インクリメンタルな変更 390
12.4データベースのロールバックとゼロダウンタイムリリース 394
12.5 テストデータを管理する 397
12.6 データの管理とデプロイメントパイプライン 401
12.7 まとめ

 第13章 コンポーネントや依存関係を管理する 409
13.1 導入
13.2 アプリケーションをリリース可能な状態に保つ 411
13.3 依存関係 416
13.5 依存グラフを管理する 429
13.6 バイナリを管理する 439
13.7 Mavenを使って依存関係を管理する 441
13.8 まとめ

 第14章 高度なバージョン管理 447
14.1 導入
14.2 リビジョン管理システムの簡単な歴史 448
14.3 ブランチとマージ 454
14.5 ストリームベースのバージョン管理システム 466
14.6 メインライン上での開発 472
14.7 リリース用のブランチ 475
14.8 フィーチャによるブランチ 477
14.9 チームによるブランチ 480
14.10 まとめ

 第15章 継続的デリバリーを管理する 485
15.1 導入
15.2 構成管理およびリリース管理の成熟度モデル 487
15.3 プロジェクトのライフサイクル 489
15.4 リスク管理プロセス 497
15.5 デリバリーによくある問題 - その症状と原因 501
15.6 コンプライアンスと監査 505
15.7 まとめ

第1部 基礎
 第01章 ソフトウェアデリバリーの問題 39
1.1 導入
1.2 リリースによくあるアンチパターン 40
1.2.1 アンチパターン:ソフトウェアを手作業でデプロイする
1.2.2 アンチパターン:開発が終わってから擬似本番環境にデプロイする
1.2.3 アンチパターン:本番環境について手作業で構成管理を行う

1.3 もっとうまくできないだろうか? 47
1.4 どうすれば目標を達成できるだろうか? 48
1.4.1 あらゆる変更はフィードバックプロセスを引き起こさなければならない
1.4.2 フィードバックはできる限り早く受け取らなければならない
1.4.3 デリバリーチームはフィードバックを受けとり、それに対応しなければならない
1.4.4 このプロセスはスケールするのか?

1.5 どんな恩恵を受けられるのか? 54
1.5.1 チームに権限を与える
1.5.2 エラーを削減する
1.5.3 ストレスを低減する
1.5.4 デプロイメントの柔軟性
1.5.5 「できるようになりたければ、練習しろ」

1.6 リリース候補 60
1.6.1 あらゆるチェックインは潜在的にリリースにつながる

1.7 ソフトウェアデリバリーの原則 62
1.7.1 ソフトウェアをリリースするための、反復可能で信頼できるプロセスを作り上げよ
1.7.2 ほとんどすべてを自動化せよ
1.7.3 すべてバージョン管理せよ
1.7.4 痛みを伴うものはこまめに実施し、痛い思いは早めにしておけ
1.7.5 品質を作り込め
1.7.6 完了したとはリリースしたということだ
1.7.7 誰もがデリバリープロセスに対して責任を負う
1.7.8 継続的改善

1.8 まとめ

 第02章 構成管理 69
2.1 導入
2.2 バージョン管理を使う 70
2.2.1 ひとつ残らずすべてバージョン管理に保存せよ
2.2.2 定期的にtrunkにチェックインせよ
2.2.3 意味のあるコミットメッセージを使え

2.3 依存関係の管理 76
2.3.1 外部ライブラリを管理する
2.3.2 コンポーネントを管理する
 
2.4 ソフトウェア設定を管理する 78
2.4.1 設定と柔軟性
2.4.2 設定の種類
2.4.3 アプリケーションの設定を管理する
2.4.4 アプリケーションをまたいで設定を管理する
2.4.5 アプリケーション構成管理の原則

2.5 環境を管理する 88
2.5.1 環境管理のためのツール
2.5.2 変更プロセスを管理する

2.6 まとめ

3.1 導入
3.2.1 始める前に必要なもの
3.2.2 基本的な継続的インテグレーションシステム

3.3.1 定期的にチェックインせよ
3.3.2 包括的な自動テストスイートを作成せよ
3.3.3 ビルドプロセスとテストプロセスを短く保て
3.3.4 開発ワークスペースを管理する

3.4 継続的インテグレーションソフトウェアを使用する 104
3.4.1 基本的な操作
3.4.2 オプション機能

3.5 基本的なプラクティス 107
3.5.1 ビルドが壊れているときにはチェックインするな
3.5.2 コミットする前に、常にローカルでコミットテストを実行せよあるいは代わりにCIサーバーにやってもらえ
3.5.3 次の作業を始める前に、コミットテストが通るまで待て
3.5.4 ビルドが壊れているのに、家に帰ってはならない
3.5.5 常に以前のリビジョンに戻す準備をしておくこと
3.5.6 リバーとする前にタイムボックスを切って修正する
3.5.7 失敗したテストをコメントアウトするな
3.5.8 自分が変更してビルドが壊れたら、すべてに対して責任をとれ

3.6 やったほうがいいプラクティス 113
3.6.2 アーキテクチャ上の違反事項があった場合にビルドを失敗させる
3.6.3 テストが遅い場合にビルドを失敗させる
3.6.4 警告やコードスタイルの違反があったときにビルドを失敗させる

3.7 分散したチーム 117
3.7.1 プロセスに与えるインパク
3.7.3 技術的な問題
3.7.4 代替案
 
3.9 まとめ

 第04章 テスト戦略を実装する 127
4.1 導入
4.2 テストの種類 129
4.2.1 開発プロセスをサポートするビジネス視点のテスト
4.2.2 受け入れテストを自動化する
4.2.3 開発プロセスをサポートする技術視点のテスト
4.2.4 プロジェクトの評価をするビジネス視点のテスト
4.2.5 プロジェクトを評価する技術視点のテスト
4.2.6 テストダブル

4.3 実際に起こり得る状況と戦略 137
4.3.1 新規プロジェクト
4.3.2 プロジェクトの途中
4.3.3 レガシーシステム
4.3.4 インテグレーションテスト

4.4 プロセス 144
4.4.1 血管バックログを管理する

4.5 まとめ


第2部 デプロイメント パイプライン
 第05章 デプロイメント パイプラインの解剖学 151
5.1 導入
5.2 デプロイメントパイプラインとは何か? 153
5.2.1 基本的なデプロイメントパイプライン

5.3デプロイメントパイプラインのプラクティス 159
5.3.1 バイナリをビルドするのは1回限りとせよ
5.3.2 あらゆる環境に対して同じやり方でデプロイせよ
5.3.3 デプロイメントをスモークテストせよ
5.3.4 本番のコピーにデプロイせよ
5.3.5 各変更は直ちにパイプライン全体を通り抜けなければならない
5.3.6 パイプラインのどの部分であっても、失敗したらラインを止めよ

5.4 コミットステージ 166
5.4.1 コミットステージのベストプラクティス

5.5 自動受け入れテストという関門 169
5.5.1 自動受け入れテストのベストプラクティス

5.6 後に続くテストステージ 173
5.6.1 手動テスト
5.6.2 非機能のテスト

5.7 リリースに備える 176
5.7.1 デプロイメントとリリースを自動化する
5.7.2 変更をバックアウトする
5.7.3 成功を積み重ねる

5.8デプロイメントパイプラインを実装する 180
5.8.1 バリューストリームをモデリングし、働くスケルトンを作成する
5.8.2 ビルドとデプロイメントプロセスを自動化する
5.8.3 ユニットテストとコード解析を自動化する
5.8.4 受け入れテストを自動化する
5.8.5 パイプラインを進化させる

5.9 メトリクス 186
5.10 まとめ

 第06章 ビルド・デプロイメントスクリプト 191
6.1 導入
6.2 ビルドツールの概要 192
6.2.1 Make
6.2.2 Ant
6.2.3 NAntMSBuild
6.2.4 Maven
6.2.5 Rake
6.2.6 Builder
6.2.7 Psake

6.3 ビルドスクリプトとデプロイメントパイプラインの原則とプラクティス 200
6.3.1 デプロイメントパイプラインのステージそれぞれに対してスクリプトを書け
6.3.2 アプリケーションをデプロイするのに適切なテクノロジーを使え
6.3.3 すべての環境にデプロイするのに、同じスクリプトを使え
6.3.4 OSのパッケージングツールを使え
6.3.5 デプロイメントプロセスが冪等(べきとう)であることを保証せよ
6.3.6 デプロイメントシステムをインクリメンタルに進化させよ

6.4 JVMを対象としたアプリケーションのためのプロジェクト構造 206
6.4.1 プロジェクトのレイアウト
6.4.2 ソースコードを管理する
6.4.3 テストを管理する
6.4.4ビルドの成果物を管理する
6.4.5 ライブラリを管理する

6.5 デプロイメントスクリプト 210
6.5.1 デプロイレイヤとテストレイヤ
6.5.2 環境設定をテストする

6.6 コツと裏技 214
6.6.1 常に相対パスを使え
6.6.2 手作業を根絶せよ
6.6.3 バイナリからバージョン管理へのトレーサビリティを組み込め
6.6.4 ビルド時にバイナリをバージョン管理にチェックインするな
6.6.5 テストが失敗してもビルドは続けよ
6.6.6 統合スモークテストでアプリケーションに制約をかけよ
6.6.7 .NETのコツと裏技

6.7 まとめ

 第07章 コミットステージ 221
7.1 導入
7.2 コミットステの原則とプラクティス 222
7.2.1 役に立つフィードバックを素早く提供せよ
7.2.2 どういうときにコミットステージを止めるべきか?
7.2.3 コミットステージを丁寧に整備せよ
7.2.4 開発者に所有権を与えよ
7.2.5 きわめて大規模なチームにはビルドマスターを置け
 
7.3 コミットステージの結果 227
7.3.1 成果物リポジトリ

7.4 コミットテストスイートの原則とプラクティス 230
7.4.1 ユーザーインターフェイスを避けよ
7.4.2 DIを使用せよ
7.4.3 データベースを避けよ
7.4.4 ユニットテストでの非同期処理を避けよ
7.4.5 テストダブルを利用する
7.4.6 テスト内の状態を最低限に抑える
7.4.7 時間の概念を偽装する
7.4.8 しらみつぶり

7.5 まとめ

 第08章 自動受け入れテスト 241
8.1 導入
8.2 なぜ自動受け入れテストが欠かせないのか? 242
8.2.1 保守しやすい受け入れテストスイートの作り方
8.2.2 GUIを叩いてテストする

8.3 受け入れテストを作成する 247
8.3.1 アナリストとテスターの役割
8.3.2 イテレーティブなプロジェクトにおける分析
8.3.3 実行可能な仕様としての受け入れ基準

8.4 アプリケーションドライバレイヤ 253
8.4.1 受け入れ基準の表現方法
8.4.2 ウィンドウドライバパターン:テストとGUI疎結合にする

8.5 受け入れテストを実装する 259
8.5.1 受け入れテストにおける状態
8.5.2 プロセス境界・カプセル化・テスト
8.5.3 非同期とタイムアウトを管理する
8.5.4 テストダブルを利用する

8.6 受け入れテストステージ 269
8.6.1 受け入れテストをグリーンに保つ
8.6.2 デプロイメントテスト

8.7 受け入れテストのパフォーマンス 275
8.7.1 共通のタスクはリファクタリングせよ
8.7.2 高価なリソースは共有せよ
8.7.3 並列テスト
8.7.4 コンピュートグリッドを用いる

8.8 まとめ


 第09章 非機能要件をテストする 281
9.1 導入
9.2 非機能用件を管理する 282
9.2.1 非機能要件を分析する

9.3 キャパシティを確保するためのプログラミング 284

9.4 キャパシティを計測する 287
9.4.1 キャパシティテストの成功・失敗の判断基準は?

9.5キャパシティテスト環境 291

9.6キャパシティテストを自動化する 294
9.6.1 ユーザーインターフェイス経由のキャパシティテスト
9.6.2 サービスや公開APIに対するインタラクションを記録する
9.6.3 記録したインタラクションテンプレートを使う
9.6.4 キャパシティテスト用スタブを使ったテスト作り

9.7キャパシティテストをデプロイメントパイプラインに追加する 302

9.8キャパシティテストシステムのもうひとつの利点 304

9.9 まとめ


 第10章 アプリケーションをデプロイ・リリースする 307
10.1 導入

10.2 リリース戦略を作成する 308
10.2.1 リリース計画
10.2.2 製品をリリースする

10.3 アプリケーションをデプロイする 310
10.3.1 最初のデプロイメント
10.3.2 リリースプロセスをモデル化し、ビルドを反映する
10.3.3 設定を反映させる
10.3.4 オーケストレーション
10.3.5 ステージング環境へのデプロイメント

10.4 デプロイメントのロールバック、そしてゼロダウンタイム・リリース 317
10.4.1 直近の正常動作するバージョンの再デプロイメントによるロールバック
10.4.2 ゼロダウンタイム・リリース
10.4.3 ブルーグリーン・デプロイメント
10.4.4 カナリアリリース

10.5 緊急修正 324
10.6 継続的デプロイメント 325
10.6.1 ユーザーがインストールするソフトウェアを継続的にリリースする

10.7 ヒントと裏技 329
10.7.1 実際にデプロイメントを行なう人たちを、デプロイメントプロセスの策定に参加させよ
10.7.2 デプロイメント作業を記録せよ
10.7.3 古いファイルは削除せず、移動せよ
10.7.4 デプロイメントはチーム全体で責任を持つ
10.7.5 サーバーアプリケーションにGUIを持たせない
10.7.6 最初のデプロイメントにはウォームアップ期間を持たせよ
10.7.7 失敗は早めに
10.7.8 本番環境を直接修正するな

10.8 まとめ


第3部 デリバリー エコシステム
 第11章 基盤と環境を管理する 337
11.1 導入
11.2 運用チームのニーズを理解する 339
11.2.1 文書化と監査
11.2.2 異常発生時の警告
11.2.3 ITサービスの継続計画
11.2.4 運用チームが慣れている技術を使え

11.3 基盤をモデリングし、管理する 343
11.3.1 基盤へのアクセスを制御する
11.3.2 基盤へ変更を加える

11.4 サーバーのプロビジョニングおよび設定を管理する 348
11.4.1 サーバーのプロビジョニング
11.4.2 進行中のサーバー管理

11.5 ミドルウェアの構成を管理する 356
11.5.1 設定を管理する
11.5.2 製品を調査せよ
11.5.3 ミドルウェアが状態をどのように扱うのかを調査せよ
11.5.4 設定APIを探せ
11.5.5 よりよいテクノロジーを採用せよ

11.6 基盤サービスを管理する 361
11.6.1 マルチホームシステム

11.7 仮想化 364
11.7.1 仮想環境を管理する
11.7.2 仮想環境とデプロイメントパイプライン
11.7.3 仮想環境を使った、高度に並列化したテスト
 
11.8.1 基盤のクラウド化
11.8.2 プラットフォームのクラウド化
11.8.3 ひとつで何もかもを解決する必要はない

11.9 基盤やアプリケーションを監視する 378
11.9.1 データを収集する
11.9.2 ログ出力
11.9.3 ダッシュボードを作成する
11.9.4 ふるまい駆動監視

11.10 まとめ

 第12章 データと管理する 387
12.1 導入
12.2 データベースのスクリプト処理 388
12.2.1 データベースを初期化する

12.3インクリメンタルな変更 390
12.3.1 データベースのバージョンを管理する
12.3.2 オーケストレイトされた変更を管理する

12.4データベースのロールバックとゼロダウンタイムリリース 394
12.4.1 データを失なわずにロールバックする
12.4.2 アプリケーションのデプロイをデータベースのマイグレーションから分離する

12.5 テストデータを管理する 397
12.5.1 仮のデータベースでのユニットテスト
12.5.2 テストとデータのつながりを管理する
12.5.3 テストの分離
12.5.4 準備と後始末
12.5.5 一貫したテストシナリオ

12.6 データの管理とデプロイメントパイプライン 401
12.6.1 コミットステージでのテストにおけるデータ
12.6.2 受け入れテストにおけるデータ
12.6.3 キャパシティテストにおけるデータ
12.6.4 その他のテストステージにおけるデータ

12.7 まとめ

 第13章 コンポーネントや依存関係を管理する 409
13.1 導入
13.2 アプリケーションをリリース可能な状態に保つ 411
13.2.1 新機能は完成するまで隠せ
13.2.2 すべての変更はインクリメンタルに
13.2.3 抽象化によるブランチ
 
13.3 依存関係 416
13.3.1 依存地獄
13.3.2 ライブラリを管理する

13.4.1 コードベースをコンポーネントに分割する方法
13.4.2 コンポーネントをパイプライン化する
13.4.3 インテグレーションパイプライン

13.5 依存グラフを管理する 429
13.5.1 依存グラフを作成する
13.5.2 依存グラフをパイプライン化する
13.5.3 いつビルドすべきか?
13.5.4 慎重な楽天主義
13.5.5 循環依存

13.6 バイナリを管理する 439
13.6.1 成果物リポジトリの活用法
13.6.2 デプロイメントパイプラインと成果物リポジトリとのやりとり

13.7 Mavenを使って依存関係を管理する 441
13.7.1 Mavenでの依存関係のリファクタリング

13.8 まとめ

 第14章 高度なバージョン管理 447
14.1 導入
14.2 リビジョン管理システムの簡単な歴史 448
14.2.1 CVS
14.2.2 Subversion
14.2.4 悲観的ロックをやめろ

14.3 ブランチとマージ 454
14.3.1 マージ
14.3.2 ブランチ、ストリーム、そして継続的インテグレーション
 
14.4.2 分散型バージョン管理システムの簡単な歴史
14.4.3 企業環境における分散型バージョン管理システム
14.4.4 分散型バージョン管理システムを使う

14.5 ストリームベースのバージョン管理システム 466
14.5.1 ストリームベースのバージョン管理システムとは?
14.5.2 ストリームを使った開発モデル
14.5.3 静的ビューおよび動的ビュー

14.6 メインライン上での開発 472
14.6.1 複雑な変更をブランチなしで行なう

14.7 リリース用のブランチ 475
14.8 フィーチャによるブランチ 477
14.9 チームによるブランチ 480
14.10 まとめ

 第15章 継続的デリバリーを管理する 485
15.1 導入
15.2 構成管理およびリリース管理の成熟度モデル 487
15.2.1 成熟度モデルの使い方

15.3 プロジェクトのライフサイクル 489
15.3.1 発見期
15.3.2 開始期
15.3.3 構築期
15.3.4 開発・リリース期
15.3.5 運用期
 
15.4 リスク管理プロセス 497
15.4.1 リスク管理入門
15.4.2 リスク管理のタイムライン
15.4.3 リスク管理の実践法

15.5 デリバリーによくある問題 - その症状と原因 501
15.5.1 頻度の低いデプロイメント・バグのあるデプロイメント
15.5.2 貧弱な品質のアプリケーション
15.5.3 管理が貧弱な継続的インテグレーションプロセス
15.5.4 貧弱な構成管理

15.6 コンプライアンスと監査 505
15.6.1 文書化よりも自動化を
15.6.2 トレーサビリティを確保する
15.6.3 サイロで作業する
15.6.4 変更管理

15.7 まとめ



ハンブル,ジェズ(Humble,Jez)
さまざまなプラットフォームや技術を扱い、非営利団体やテレコム、
金融サービス、オンラインレンタル企業などのコンサルを行っている。
 
2004年以来、ThoughtWorksと、北京、バンガロール
ロンドン、サンフランシスコのThoughtWorks Studioで働いている。
 
オクスフォード大学の物理学および哲学の学士と、
ロンドン大学東洋アフリカ学部民族音楽学の修士を有している。
 
現在は、サンフランシスコに妻と娘と住んでいる


ファーレイ,デイビッド(Farley,David)
アジャイル開発テクニックのアーリーアダプターであり、1990年代前半より商用プロジェクトで、
イテレーティブな開発や継続的インテグレーション、かなりの量の自動テストなどを採用してきた。
現在、London Multi-Asset Exchange(LMAX)に勤務している


和智右桂(ワチユウケイ)
プログラマ。グロースエクスパートナーズ株式会社ITアーキテクト。
「デリバリー」をキーワードに、要件定義、方式設計から開発、
テストまでロールにとらわれずに仕事をしている。
認定プロダクトオーナー、認定スクラムマスター


高木正弘(タカギマサヒロ)
1972年大阪府生まれ。さまざまなプロジェクトでドキュメントの翻訳に携わるようになる
 
 
 
 
 

Testです

Evernoteとはてなブログが連携できるようになったみたいです。

記念とテストを兼ねて、(特に書く事はないけど)ブログを作成。

 

Evernoteと連携してノベルティをゲット! Evernoteで保存したノートをブログで活用できる「Evernote貼り付け機能」をリリースしました - はてなブログ開発ブログ http://staff.hatenablog.com/entry/evernote-campaign

 

読んだ本をEvernoteに貼り付けています。

本のあらすじに「一番最初に読むアルゴリズムの本」と紹介されています。

とっても読みやすい本です。

インプレスの公式サイトには掲載されていない詳細な目次を書き出してみました。

 

f:id:kireifish:20121206173550g:plain


http://www.impressjapan.jp/books/3201

アルゴリズムを、はじめよう
伊藤 静香 /2012年05月14日 /256P / amazon


プログラミングの基礎知識から身に付けられるよう、
「プログラムとは何か」「アルゴリズムとは何か」から解説

本書は、アルゴリズムの入門書の中でも、一番最初に読んでいただきたいアルゴリズム超入門書です。
アルゴリズムの定石と呼ばれるものには様々な種類がありますが、プログラマ初心者が
いきなりたくさんのアルゴリズムを学ぼうとしても、途中で挫折してしまう人が多いのではないでしょうか。
 
本書は、アルゴリズムの中でもプログラマが最低限知っておくべきとされるもののみにぎゅっと絞込み、
1つひとつをとにかくていねいに解説しているため、無理なく最後まで読み終えることができます。
 
また、簡単な例でイメージを確認してからフローチャートを
少しずつ完成させていく手順で解説しているため、確実に理解することができます。

はじめに
この本ではデータ構造については、変数と配列以外は、取り上げませんでした。
理由は、アルゴリズムの勉強を始めようとして、データ構造でつまづく人が多いから。

第 1章 アルゴリズムの基本
01.アルゴリズムとは何か?
02.アルゴリズムとプログラムの関係
03.プログラム作成におけるアルゴリズム
04.いいアルゴリズムとはどういうものか?
05.なぜアルゴリズムを作る必要があるのか?
06.手順がアルゴリズムであるための条件
07.アルゴリズムの3つの基本形
08.アルゴリズムの記述方法①ー流れ図
09.アルゴリズムの記述方法②ープログラミング言語
10.アルゴリズムの記述方法③ー擬似言語
 
第 2章 変数と配列
1.変数について学ぼう
2.配列について学ぼう
 
第 3章 アルゴリズムに慣れよう
1.三角形の面積を計算するアルゴリズム
2.2つのデータの大小を判定するアルゴリズム
3.2つの変数のデータを入れ替えるアルゴリズム
4.合計値を計算するアルゴリズム
5.最大値を探すアルゴリズム
 
第 4章 線形探索法(リニアサーチ)
1.定番アルゴリズムとは?
2.探索アルゴリズムとは?
3.線型探索法のイメージをつかもう
4.線形探索法のアルゴリズム
 
第 5章 二分探索法(バイナリサーチ
1.二分探索法のイメージをつかもう
2.二分探索法のアルゴリズム
 
第 6章 ハッシュ探索法
1.ハッシュ探索法のイメージをつかもう
2.ハッシュ関数でデータを格納するアルゴリズム
3.ハッシュ探索法でデータを探索するアルゴリズム
 
第 7章 単純選択法(選択ソート)
1.整列アルゴリズムとは?
2.単純選択法のイメージをつかもう
3.単純選択法のアルゴリズム
 
第 8章 単純交換法(バブルソート
1.単純交換法のイメージをつかもう
2.単純交換法のアルゴリズム
 
第 9章 単純挿入法(挿入ソート)
1.単純挿入法のイメージをつかもう
2.単純挿入法のアルゴリズム
 
第10章 クイックソート
1.クイックソートのイメージをつかもう
2.クイックソートのアルゴリズム
3.基準値を境にしてデータを大小に分ける処理
4.分けたデータに再度同じ処理を実行する処理
 
第11章 エラトステネスのふるい(素数を求めるアルゴリズム)
1.エラトステネスのふるいとは?
2.エラトステネスのふるいのイメージをつかもう
3.アルゴリズムを流れ図で書く
4.アルゴリズムを擬似言語で書く
 
第12章 ユークリッドの互除法(最大公約数を求めるアルゴリズム)
1.ユークリッドの互除法のイメージをつかもう
2.アルゴリズムを流れ図で書く
3.アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 1章 アルゴリズムの基本
01.アルゴリズムとは何か?
・アルゴリズムとは、ひとことで言えば「手順」のこと
・料理のレシピはアルゴリズム
・楽譜もアルゴリズム
・取扱説明書もアルゴリズム
 

02.アルゴリズムとプログラムの関係
・アルゴリズムをプログラミング言語で書いたものがプログラム
 

03.プログラム作成におけるアルゴリズム
・プログラム作成の流れ
・プログラミングのはじまりはニーズ
・プログラムを設計する
・プログラミングする
・プログラムをデバッグする
・プログラムのドキュメントを作成する
 

04.いいアルゴリズムとはどういうものか?
・わかりやすい
・高速である
・効率的である
・再利用しやすい
 

05.なぜアルゴリズムを作る必要があるのか?
・いいプログラムを作るため
・プログラムの善し悪しを判断するため
・プログラム作成過程全体を効率化するため
・プログラミング技術向上のため
 

06.手順がアルゴリズムであるための条件
・正しい結果が得られる
・かならず終わる
 

07.アルゴリズムの3つの基本形
・①順次構造ーー初めから順番に処理する手順
・②選択構造ーー処理を選んで実行する手順
・③反復構造ーー同じ処理を繰り返す手順
 

08.アルゴリズムの記述方法①ー流れ図
・アルゴリズムを流れ図で表す
 

09.アルゴリズムの記述方法②ープログラミング言語
プログラミング言語にはたくさん種類がある
 

10.アルゴリズムの記述方法③ー擬似言語
・擬似言語はプログラミングには使えない
・擬似言語の記述方法
 
●順次構造の書き方
 
●選択構造の書き方
 
●反復構造の書き方
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 2章 変数と配列
1.変数について学ぼう
・データはメモリに保存される
・データの保存には変数を使う
・変数を使うときは、まず宣言する
・変数名のつけ方
・データ型とは?
・変数の宣言方法
・変数へデータを代入するには?
・変数のデータを参照するには?
 

2.配列について学ぼう
・変数には限界がある
・配列のしくみ
・配列の宣言方法
・配列の要素へデータを代入するには?
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 3章 アルゴリズムに慣れよう
1.三角形の面積を計算するアルゴリズム
・処理に分解して手順を考える
 
三角形の面積=底辺の長さ × 高さ÷2
 
この計算過程が、どのようなデータと処理から成り立っているのかを考えよう。
 
まずデータとして必要なのは「底辺の長さ」と「高さ」です。
それぞれ変数を用意して、代入する。データを取り扱うには、とりあえず変数です。
 
次に、実際に計算する処理を考えます。
「底辺の長さ」と「高さ」をかけ合わせて2で割り、「面積」を出します。
ただ計算しただけでは、計算結果がいくらになるのかを確かめることはできません。
計算した結果のデータは、もう一つ別の変数を用意して、代入することにします。
そして、「面積」のデータをコンピュータのディスプレイに表示させます。(標準出力)
 
必要な変数は、「底辺の長さ」「高さ」「面積」を代入する実数型変数が3つ、
処理は順次構造でよさそうだということがわかりました。
 
・アルゴリズムを表す流れ図を作る
変数名を、
 
「底辺の長さ」をbase,
「高さ」をheight,
「面積」をarea
 
とします。
 
次に、baseとheightにデータを入力します。(標準入力)
 
流れ図で言うと、以下のようになる。
開始 →baseとheightを入力する →base*height/2.0=area →areaを出力する →終了
 
・四則演算を表す算術演算子
算数では商を求める機能と余りを求める機能が同居しているが、
プログラミングでは、分離して表す。
 
13/3・・・4(商を表す)
13%3・・・1(余りを表す)
 
 
・アルゴリズムを擬似言語で書く
最初に変数の宣言をする。
変数の宣言は、行頭に「○」をつける。
以後の処理は行頭に「・」を書き、1つの処理を1行ずつに分けて書く。
 
○実数型:base,height,area
・baseとheightを入力する
・area←base*height/2.0
・areaを出力する
 
 
 

2.2つのデータの大小を判定するアルゴリズム
●2つのデータを比較するには、選択構造を使う。
●条件式では関係演算子を使う。
 
・2つのデータのうち、大きいのはどちらか?
 
 
・アルゴリズムを表す流れ図を作る
 
 
・データを比較する関係演算子
 
 
・アルゴリズムを擬似言語で書く
 
 

3.2つの変数のデータを入れ替えるアルゴリズム
●2つの変数のデータを直接入れ替えることはできない
●入れ替え用の変数を使う
 
・2つのデータを入れ替えるなんて、簡単?
 
 
・データ交換用の変数を使う
 
 
・アルゴリズムを擬似言語で書く
 
 

4.合計値を計算するアルゴリズム
●配列の要素を合計するには、反復構造を使う
●合計値を代入する変数sumは、初期化を行う
●変化する添字は、変数i に代入する
●反復構造では、無限ループにならないような処理を忘れずに加える
 
・単純に合計するアルゴリズムもありだけど・・・
 
・反復構造を使ったアルゴリズムを考えてみる
 
 
・アルゴリズムを擬似言語で書く
 
 

5.最大値を探すアルゴリズム
●複雑そうなときは、流れ図を作りながらアルゴリズムを考える
●その時々の最大値を格納する変数maxを使う
●変化する添字を格納する変数iを使う
●繰り返し処理が無限ループにならないような処理を入れる
 
・5つのデータのうち、一番大きいのはどれか?
 
 
・流れ図を作りながら、アルゴリズムを考える
 
 
・アルゴリズムを擬似言語で書く
 
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 4章 線形探索法(リニアサーチ)
1.定番アルゴリズムとは?
●基本的な処理手順をもっているアルゴリズムのこと
●いいプログラムを作るための考え方やヒントがたくさん詰まっている
●定番アルゴリズムの学習は、プログラミング技術の向上に役立つ
 
・定番アルゴリズムとは何か?
・定番アルゴリズムの種類
 

2.探索アルゴリズムとは?
●検索アルゴリズムとは、目的のデータを探し出すアルゴリズムのこと
●検索エンジンも探索アルゴリズムを使っている
 
・検索エンジンは探索アルゴリズムを使っている
・探索とは目的のデータを探し出すこと
 

3.線型探索法のイメージをつかもう
●線形探索法は、先頭から順番に調べて探す探索アルゴリズム
●アルゴリズムは単純で分かりやすい
●探索効率はそれほどよくない
 
・線形探索法でボールを探し出してみよう
・線形探索法の手順
 

4.線形探索法のアルゴリズム
●配列に保存されたデータを先頭から順番に探索する
●探索処理は反復構造で記述する
●反復構造では終了条件を忘れないこと
 
・配列と要素の設定
・探索処理の流れ
・反復処理にはかならず終了条件をつけること
・アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 5章 二分探索法(バイナリサーチ
1.二分探索法のイメージをつかもう
●二分探索法は、データを探す探索アルゴリズムの一つ
●あらかじめ昇順か降順に整列されているデータが対象
●探索する範囲を半分に絞りながら探索を進める
 
・二分探索法でボールを探してみよう
・①真ん中のボールの数字を見てみる
・②ふたたび真ん中のボールの数字を見てみる
・③みたび真ん中のボールの数字を見てみる
 

2.二分探索法のアルゴリズム
●二分探索法は主に3つの処理からなる
●①真ん中の要素を選ぶ処理
●②真ん中のデータと目的のデータを比較する処理
●③探索の範囲を半分に狭める処理
●目的のデータが存在しない場合の処理も忘れずに書く
 
・配列の設定
・二分探索法のアルゴリズム構成
・①真ん中の要素を選ぶ
・②真ん中の要素と目的のデータを比較する
・③探索の範囲を半分に絞る
・もし目的のデータが存在しなかったら?
・アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 6章 ハッシュ探索法
1.ハッシュ探索法のイメージをつかもう
●探索しやすいように、あらかじめ関数を使ってデータを格納しておく
●格納するのに使った関数を使い、一発でデータを探索する
 
・ハッシュ探索法の特徴
・あらかじめ探索しやすいようにボールを格納する
・ハッシュ探索法でボールを探す
 

2.ハッシュ関数でデータを格納するアルゴリズム
●データの格納先の添字を計算するにはハッシュ関数を使う
●格納先の添字がバッティングすることを衝突と言う
●衝突が起こったら、隣の空き要素にデータを格納する
 
・ハッシュ探索法のアルゴリズム構成
・配列を2つ用意する
・arrayD[0]のデータをarrayHに格納する
・arrayD[1]のデータをarrayHに格納する
・arrayD[2]のデータをarrayHに格納する
・arrayD[3]のデータをarrayHに格納する
・arrayD[4]のデータをarrayHに格納する
・arrayD[5]のデータをarrayHに格納する
・arrayD[6]のデータをarrayHに格納する
・アルゴリズムを擬似言語で書く
 

3.ハッシュ探索法でデータを探索するアルゴリズム
●データの探索には、格納に使ったのと同じハッシュ関数を使う
●探索データが存在しない場合の処理を忘れずに書く
 
・探索対象となる配列
・12が格納されている要素を探索する
・36が格納されている要素を探索する
・探索しているデータが配列に存在しない場合
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 7章 単純選択法(選択ソート)
1.整列アルゴリズムとは?
●整列アルゴリズムとは、データを昇順・降順に並べ替えるアルゴリズムのこと
●検索エンジンやExcelでも整列アルゴリズムは使われている
 
・検索エンジンやExcelでも整列は重要
・整列アルゴリズムの定番4つ
 
 

2.単純選択法のイメージをつかもう
●単純選択法は、データを並べ替える整列アルゴリズムの1つ
●一番小さなデータを選択して、先頭から順に並べ替えていく
 
・単純選択法でボールを並べ変えてみよう
・①数字が一番小さいボールを先頭のデータと交換
・②次に数字の小さいボールを2番目のボールと交換
・③3つのうち一番小さいボールを3番目のボールと交換
・④残った2つを昇順に並べ替え
 
 

3.単純選択法のアルゴリズム
●昇順に整列する単純選択法は、次の2つの手順からできている
●①探索範囲の最小値を探す処理
●②探索範囲の最小値を先頭要素と交換する処理
 
・配列の設定
・探索処理の流れ
・①array[i]からarray[4]の中の最小値を探す
・②最小値とarray[i]のデータを交換する
・3つの処理を組み合わせて流れ図が完成
・アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 8章 単純交換法(バブルソート
1.単純交換法のイメージをつかもう
●単純交換法は、データを並べ替える整列アルゴリズムの1つ
●隣合ったデータを交換する処理を繰り返して、全体を整列する
●単純なアルゴリズムだが、実行速度は遅い
 
・単純交換法でボールを昇順に並べ変えてみよう
・①0番枠に1のボールを持っていく
・②1番枠に2のボールを持っていく
・③2番枠に3のボールを持っていく
・④3番枠に4のボールを持っていく
 

2.単純交換法のアルゴリズム
●昇順に整列させる単純交換法は、2つの手順の組み合わせからなる
●①右端の要素から順に、隣合ったデータを昇順に並べ替える
●②左端の要素から1つずつ順番に、データが昇順に整列していく
 
・配列の設定
・右端から順に、隣り合ったデータを昇順に並べ替える
・左端の要素から順に、入るデータを確定させていく
・アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第 9章 単純挿入法(挿入ソート)
1.単純挿入法のイメージをつかもう
●単純挿入法は、データを並べ替える整列アルゴリズムの1つ
●正しい順序になるようにデータを挿入していく
●単純挿入法は、挿入ソート、基本挿入法、挿入法とも呼ばれる
 
・単純挿入法でボールを昇順に並べ替えてみよう
・1番目の枠のボールを正しい位置に挿入する
・2番目の枠のボールを正しい位置に挿入する
・3番目の枠のボールを正しい位置に挿入する
・4番目の枠のボールを正しい位置に挿入する
 

2.単純挿入法のアルゴリズム
●挿入したいデータは別に変数を用意して代入しておく
●変数のデータを、整列済みデータと順番に比較していく
●変数のデータより小さいデータが見つかったら、その後ろの要素に変数のデータを代入する
 
・配列の設定
・array[1]のデータを正しい位置に挿入したい
・array[2]のデータを正しい位置に挿入したい
・array[3]のデータを正しい位置に挿入したい
・アルゴリズムを擬似言語で書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第10章 クイックソート
1.クイックソートのイメージをつかもう
クイックソートは、データを並べ替える整列アルゴリズムの1つ
●データを大小のグループ2つに分割しながら全体を整列していくアルゴリズム
●実行速度が速いのが特徴
 
クイックソートでボールを昇順ニ並べ替えてみよう
・先頭の5を基準にしてボールを大小に分ける
・先頭の3を基準にしてボールを大小に分ける
・先頭の2を基準にしてボールを大小に分ける
・先頭の8を基準にしてボールを大小に分ける
・先頭の7を基準にしてボールを大小に分ける
 

2.クイックソートのアルゴリズム
クイックソートは、大きく分けて2つの処理から構成されている
 

3.基準値を境にしてデータを大小に分ける処理
●データを大小に分ける処理が、クイックソートの中心的な処理
●配列の左と右から、それぞれ変数を動かして、大小に並べ替えていく
 
・配列の設定
・変数の設定
・変数i を使って、基準値より大きい要素を探す
・変数k を使って、基準値より小さい要素を探す
・大きいデータと小さいデータを交換する
・データを見つけて交換する処理を繰り返す
・基準値を大小データの真ん中に移動する
 

4.分けたデータに再度同じ処理を実行する処理
●「基準値を堺にして、データを大小に分ける」処理を副プログラムにする
●副プログラムの中で副プログラムを使うことで、繰り返し処理を実行する
 
・QuickSortを副プログラムにする
・QuickSortの中でQuickSortを使う
 
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第11章 エラトステネスのふるい(素数を求めるアルゴリズム)
1.エラトステネスのふるいとは?
●エラトステネスのふるいとは、素数を見つけ出すアルゴリズム
●素数とは、2以上の整数で、1とその数自身以外では割り切れない数
●素数は、並んでいる間隔が不規則でランダムで見つけにくい
 
・素数のおさらい
・素数かどうかを見分けるのは案外難しい
・エラトステネスのふるいは素数を発見する方法
 

2.エラトステネスのふるいのイメージをつかもう
・エラトステネスのふるいの構成
・10までの整数データを用意するには?
・要素を使って素数の倍数を取り除く
・ふるわれずに残った数を出力する
 

3.アルゴリズムを流れ図で書く
・配列の設定
・2の倍数を取り除く
・3の倍数を取り除く
・次の素数を探す
・次の素数の倍数を取り除く
・要素が1の添字を出力する
 

4.アルゴリズムを擬似言語で書く
・変数と配列の設定
・本体の処理の部分を書く
 
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
第12章 ユークリッドの互除法(最大公約数を求めるアルゴリズム)
1.ユークリッドの互除法のイメージをつかもう
・最大公約数のおさらい
・最大公約数の求め方
・143と221でユークリッドの互除法を試してみよう
 

2.アルゴリズムを流れ図で書く
・変数の設定
・大きい方の数を小さい方の数で割る
・余りr が 0 かどうか確かめる
・小さい方の数を余りで割る処理を、反復構造にする
 

3.アルゴリズムを擬似言語で書く
・ループ記号を使った前判定型反復構造にする
・後判定型反復構造を使ってみる
・両方のアルゴリズムを擬似言語で書く
 
 
 
 
おわりに
 
最先端の機械を作って製品を作るのは簡単で、しかも楽なことだが、
基本技術を固める前に楽なほうに流れていってしまった。
俺のような基本的なことがきちんとできるローテクが、今、我が世の春を謳歌しているんだ。
 
 

東京生まれ。東京大学文学部卒業。
出版社に勤務の後、テクニカルライターとして独立。
 
著書に
 
「1週間で基本情報技術者の基礎が学べる本」
 
がある。