C MAGAZINE連載(2003年〜2005年)
結城浩
こんにちは、結城浩です。
ここは、月刊誌『C MAGAZINE』で『プログラミングの基礎テクニック』という連載を書いていたときのサポートページです。
この連載では、 問題と解決の間のギャップを埋めるテクニックとして、
の中から、よく使われるものを選び、具体的なプログラム例と図を使って解説します。
プログラミング言語としてはJavaやCなどを用いています。 文法は理解しているけれど、経験が浅いという人を対象にして解説しますが、 できれば、熟練者にとっても新しい発見があるような内容も盛り込んでいます。
デバイスへのアクセスに時間がかかる場合、 アクセス回数を減らすことによって高速化をはかることができます。 利用者とデバイスの間にバッファというメモリ領域を用意することで、 デバイスへのアクセス回数を減らすことができます。
いま、準備するのに時間がかかるデータを扱っているとしましょう。 準備ができたデータを、 キャッシュと呼ばれるメモリ領域に一時的に保持しておけば、 スピードアップをはかることができます。
最も有名な検索アルゴリズム、バイナリサーチを紹介します。 バイナリサーチは一言で言えば「検索対象を毎回半分に減らしていく」という検索方法です。 検索対象データを繰り返して二分することで、log nのオーダーで検索対象を見つけることができます。 ただし、前もってデータはソートされている必要があります。
最も高速なソートアルゴリズム、クイックソートを紹介します。 クイックソートは一言で言えば「数列を、注目している数よりも大きい部分と小さい部分に分けていく」というソート方法です。 挿入ソートと比較してみます。
レベルNの問題を、レベルN-1以下の問題に帰着して記述する再帰という方法を紹介します。 階乗の計算をCで書いたり、ListのS式のサブセットをJavaで解析したりします。
構造を持ったデータをファイルとして保存したり、 ネットワークを通じて送ったりする必要が生じたとしましょう。 その場合、メモリ上のデータをそのまま送るわけにはいきませんから、 複雑な構造を壊さないように注意しながら一次元のバイト列に変換します。 これがシリアライゼーションです。 PerlとJavaでシリアライゼーションの例を示します。
リフレクションというのは、 「プログラムがプログラム自身の情報を取得・実行することができる」という性質のことです。 オブジェクト指向プログラミングで言えば 「オブジェクトがオブジェクト自身のことを知っている」と表現してもよいでしょう。 リフレクションの機能を利用して、簡単なクラスブラウザをJavaで作ります。
非同期的な処理を行うための技法としてCallbackとFutureを紹介します。 Callbackというのは、呼び出した先から呼び出し元を「呼び返してもらう」ことです。 処理の結果が必要なときには、Futureが役に立つことがあります。 Callbackでは処理の結果をいわば「送りつけられる」ことになりますが、 Futureを使うと、非同期的な処理を行いながらも、処理の結果を自然な形で取得することができます。
「定数」という概念を拡張したImmutableを紹介します。 C, Perl, Java, C#などの言語を通して「状態が変化しない」ということの意味を考えてみましょう。
Double Bufferingというのは、 GUIで画面のちらつきを防止するためによく使われるテクニックです。 自前でDouble Bufferingを作る例と、 JavaのBufferStrategyを使う例を示します。
通信時や保存時のデータサイズを小さくする圧縮というテクニックを紹介します。 ランレングス圧縮の簡単な例と、GZIPInputStreamの例、暗号と組み合わせる例をJavaで作ります。
データ検索を高速に行うための技法ハッシュテーブルを紹介します。
ソースコードに埋め込むドキュメントとそれを変換するツールの紹介をします。 PerlのPODとJavaのjavadocを中心にお話します。
Noninteractiveというちょっと変わった切り口からプログラムについて考えてみましょう。 筆者が作成した「はてなダイアリーライター」というコマンドラインツールを紹介します。
「オブジェクト指向」の基本である「オブジェクト」の話をします。 よく使うものを「まとめる」観点から、再利用や修正の容易さについて考えましょう。 また、筆者が作成した KissReader を紹介します。
関数を通常の値のようにして扱う「クロージャ」の話をします。 Perl, Java, Haskellでクロージャを作ります。
Dependency Injection(依存性の注入)を紹介します。 シンプルなプログラムを段階を追って改良し、非常に単純なDIContainerを作ってみます。