即席プログラマー養成読本 α版

やあ、ようこそ職業プログラマの世界へ!

この文書は、何の準備もなくコの業界に飛び込んでしまった文系プログラマ(候補)や、将来的にコの業界に就職するかもしれないし就職する気もあるけど基礎が足りてないと自覚している学生に、比較的短期間で商品知識以外の職業プログラマの技術的基礎を叩き込むための技術書のリストだ。対象が対象だけに、そこそこやさしめかつ極力高くない本を選んでいるつもりだ。*1

比較的短期間ってどのくらいか、だって? 驚くなよ、3年だ

――えーと、3年なんて長すぎる? またまたご冗談を。10日間とか半年で何となかるだなんて信じてもないくせに。それぐらいで何とかなるのは、それなりに下地のある人か、非常に才能に溢れている人ぐらいなのよ。これを読んでいるあなたが、そんな一握りの人たちの仲間だというなら、それは非常に喜ばしいことだよね。でもそういう人はごくわずか。世の中は「自称『普通の人』」で溢れているものさ。

3年という区切りは、その間に常に新しいことを学び続けてきたと自信をもって言えるのなら、次の展開を考える良いタイミングだ。本格的に開発者の道に進むのか、開発者以外のキャリアに進むのか。コの業界から足を洗うのもありだ。いや本当に。コの業界だけが働き先ではないからね。

このリストの目的は「技術的基礎を叩き込む」だ。これはつまり、システム開発において抽象度の低い部分であるコンストラクション(詳細設計、実装、開発者テスト、デバッグ)の基礎体力をつける、ということだ。

システム分析・設計は抽象度の高いところから始まるけど、最終的にはソースコード(時にはオブジェクトコード)という抽象度の低い電算機寄りの世界に到達しなくてはならない。いくら設計がすばらしくても実装がグズグズならダメだから、コンストラクションの技術は必要だ。その逆に、いくらコンストラクションの技術が高くても、肝心の設計が「実装の都合」を全くもって無視していたらダメだ。その設計は使い物にならない机上の空論にすぎない。使い物になる設計にしたいなら、どこかの段階で「実装の都合」も考慮する必要がある。その「実装の都合」を知る方法の1つが「コンストラクションの世界を経験する」だ。

設計と実装の間に断絶なんてない。そこにあるのは、設計から実装にいたる1つのスペクトラム(連続体)だ。だから、設計と実装が分断された別物だという考えは改めるべきだ(そんな風に考えても、何も良いことはないよ)。どちらも学ぶべきなんだ。

このリストには欠けている部分がある。「技術的基礎を叩き込む」なので技術以外の要素が省かれている――だけではなく、特定のプログラミング言語や開発ツールといった商品知識の本も極力載せていない。

なぜなのか? 使用する言語やツールは、開発対象やチーム内文化によって変化するからだ。だから、まずは新人教育や学校の講義で教わるだろう言語・ツールに慣れてほしい。特に新人教育の場合、君の先輩は、例えばC#Javaの案件が圧倒的に多いのにCobolを教えようとはしないはずだ――外部要因がなければ、だけど。

それと、これを書いている私は、どちらかと言えば組み込み系のCプログラマで、少々移植性のあるミドルウェア・ライブラリを実装するのが本職の人なので、そういった方面のバイアスがかかっているだろうことを記しておこう。

とりあえず3年間、新人教育やOJTの合間をぬいつつ、このリストの本を読んで実践してみよう。あ、でも不幸にも炎上案件に巻き込まれてしまったなら、無理せず休もう。

『ディジタル作法』

まずは基礎知識から。技術面の下地がない人がコンピュータやネットワークについて概要を学ぶのにちょうどよい本といえば『ディジタル作法』だ。

ディジタル作法 −カーニハン先生の「情報」教室−

ディジタル作法 −カーニハン先生の「情報」教室−

「未来の大統領のための情報教科書」という按配で、要は技術系ではない人がコンピューティングについて正しく理解するための基礎知識がまとめられている。技術系の人も元々は非技術系だった訳で、これから技術系を目指すにあたってのスタート地点にちょうどよい本だ。

作者が作者だけに*2、類似本と比較すると技術的な土台がしっかりしているし、類書で省略されていたりたとえ話で誤魔化していたりする部分も現実に即してかつ分かりやすく書いてある。

この文書は技術者予備群を対象として書いている。なので、下手な省略やたとえ話で誤魔化すような本ではなく、真っ向から立ち向かって解説している本書のような本を推奨している。読者には、そういう本を読んで理解しようとする気概を求めたいんだ。この仕事、理解が曖昧なままに表面だけ見て突き進むと、結果として失敗することが9割だからね。ちなみに残りの1割は「大失敗する」だ。システム開発は、かくも険しいものなりて。

『痛快!コンピュータ学』

少し古いけど、『ディジタル作法』よりも情報科学寄りの入門書として、これも挙げておく。

痛快!コンピュータ学 (集英社文庫)

痛快!コンピュータ学 (集英社文庫)

この本も技術的土台はしっかりしている。コンピュータの原理については『ディジタル作法』よりも少し踏み込んだ内容になっている。

なによりも安い! さすが文庫本。

17年前(つまり前世紀)の本なので、時事ネタこそ古びているのだけど……でも内容は結構良くてかつコンパクトにまとまっている良書なのよ、半導体のプロセスと量子力学の壁の話(今は10nmと7nmでの競争かな?)とか、さらっとだけど記述があるぐらいには。

『CODE コードから見たコンピュータのからくり』とアーキテクチャ本を一冊

コンピュータの原理について、もう少し突っ込んだ内容を学びたい人には、結構ボリュームがあるけど『CODE コードから見たコンピュータのからくり』を推奨する。

CODE コードから見たコンピュータのからくり

CODE コードから見たコンピュータのからくり

基本情報技術者の勉強をしていると、2進数や論理演算や論理ゲートの話が出てくる。この本を読めば、それらの要素が現実のコンピュータとどう結びついているのか分かるはずだ。

論理ゲートなどの話は、計算機科学的にはコンピュータ・アーキテクチャの話だと思う。大学の情報学部なんかでは、履修する講義によってはパタヘネ本こと『コンピュータの構成と設計』を買わされる気がする。

コンピュータの構成と設計 第5版 上

コンピュータの構成と設計 第5版 上

コンピュータの構成と設計 第5版 下

コンピュータの構成と設計 第5版 下

個人的には、もはや「『コンピュータの構成と設計』ことパタヘネ本」と言った方が適切じゃないかと思うんだけど、どうだろう。

コンパクトにまとまった本として『コンピュータアーキテクチャのエッセンス』もあるけど、一部微妙に翻訳が……。それさえなければ、懐にやさしい良い本なのだけど。

コンピュータアーキテクチャのエッセンス (IT Architects Archiveシリーズ)

コンピュータアーキテクチャのエッセンス (IT Architects Archiveシリーズ)

  • 作者: ダグラス・E・カマー,Douglas E. Comer,鈴木貢,中條拓伯,仲谷栄伸,並木美太郎
  • 出版社/メーカー: 翔泳社
  • 発売日: 2007/06/01
  • メディア: 単行本(ソフトカバー)
  • 購入: 2人 クリック: 107回
  • この商品を含むブログ (21件) を見る

『プログラミング作法』

ソースコードを記述するようになったら、『プログラミング作法』を読もう。以下のどちらも内容は同じだ。

プログラミング作法

プログラミング作法

プログラミング作法

プログラミング作法

この本には、設計*3・実装・デバッグ・テストまで、コンストラクション一通りについて、プロのプログラマがとるべき所作がまとめられている。

所作や癖は、一度身についてしまうと、後で直すのが大変だ。だから、最初が肝心。鉄は熱いうちに打てということわざに従って、キャリアの初期にこそ正しく王道の所作を学ぶべきだ。そのためにも、この本を活用すべきだ。

ちなみに著者の片方は『ディジタル作法』の人。もう一人も界隈では有名というか、最近はGo言語で有名というか、そういう人だ。

『リーダブルコード』

システム開発は協調作業だ。ソースコードは他人や「数年後の自分自身」も読む。自分しか読まないと思って適当に書いたコードが、気づかぬうちに他人に引き継がれてしまい、読み難さゆえに陰で悪口の対象となることはままあることだ。例え引き継がれなくとも、数年後の自分が解読に苦労する羽目になることが大半だ。

だからプログラマは、いつでも「他人に読みやすい形式」でソースコードを記述しなくてはならない。

じゃあ「他人に読みやすい形式」って何だろう? その辺のエッセンスがこの本に凝縮されている。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

この本が出るまでは、一冊にまとめられた知見を得るためには、他人のソースコード(それも筋の良いもの)を読んで勉強するか、『Code Complete』みたいな厚くて高い本に手を出すしかなかったと思う。良い時代になったね。

名前重要。別に『リーダブルコード』で扱っているのは「名前」だけではないけど、名前重要。ソースコードは名詞の集合体かと思えるほど名前が溢れているからだ。名付けの極意は「名は体を表す」だと思っているけど、なかなか難しい。

『ソフトウェアの複合/構造化設計』

関数(プロシージャ/サブルーチン/etc)の作り方に迷ったら、古典だけどこんな本がある。もうちょっと新しい本がないものかなあ。

ソフトウェアの複合/構造化設計

ソフトウェアの複合/構造化設計

ざっくり言うと、この本の中で、基本情報技術者に出てくるモジュール強度/結合度・STS分割・TR分割・ジャクソン法について例題を元に解説している*4。なので、読んで実践することで、関数による機能分割を理詰めで行えるようになる。

もちろん、こういう技法は常に適用できるわけではないのだけど、でも関数を作る時に、関数の良し悪しを判断する基準の一つとして使える(あくまでも「基準の一つとして」だよ?)。札は多いに越したことはない。

最初はモジュール強度/結合度。次に状態遷移*5とジャクソン法(ジャクソン構造図って、文字列処理に適用したら、正規表現そのものだよね)。これだけでも、意識することで随分と見通しのよい関数群になる。

この本は古典なので、関数による機能分割について、書かれていないことは山ほどあることに注意してほしい。もう少し新しくかつフォーマルかつプログラマ向けな本がないかなあ。

アルゴリズムとデータ構造」についての基礎本を一冊

ハイ皆様、アルゴリズムとデータ構造にひれ伏しましょう :)

その昔『アルゴリズム+データ構造=プログラム』なんて本*6があったのだけど、実際のところ、現在でも大規模プログラミングにおける「モジュール」や「クラス」といった粒度の世界では一般的なアルゴリズム・データ構造は非常に重要な要素だ。

というのも、そもそも一般的なアルゴリズム・データ構造は小規模なプログラミングにおける重要要素なのだけれども、大規模プログラミングでは分割統治が当たり前な訳で、最終的に、分割された個々のパーツは小規模プログラミングの対象となる。ならば、個々のパーツたる「モジュール」や「クラス」の実装でも、一般的なアルゴリズム・データ構造は重要な要素となるのだ。*7

もう1つ言っておくと、システムが階層化された結果として、プログラムの上位階層の実装があたかも「便利なAPIを使った小規模プログラミング」風となった場合には、その上位階層の実装(≒小規模プログラミング)でも一般的なアルゴリズム・データ構造が重要な要素となりうる余地がある。

高度なアルゴリズム・データ構造は、当然ながら重要なのだけれど、そうではない一般的なアルゴリズム・データ構造も、地味だけど意外と重要なのだ。

現実のプログラミングでは、どちらかと言えばアルゴリズムよりはデータ構造の方が重視されることが多いと思う。ロブ・パイクの「Data dominates」は至言であり、同時に、これは私事なのだけど、私がかつて師匠に言われたことでもある。

アルゴリズムとデータ構造に関する本は色々あって、個人的には『アルゴリズムイントロダクション 第3版 第1巻: 基礎・ソート・データ構造・数学 (世界標準MIT教科書)』と『アルゴリズムイントロダクション 第3版 第2巻: 高度な設計と解析手法・高度なデータ構造・グラフアルゴリズム (世界標準MIT教科書)』とか、『入門 データ構造とアルゴリズム』とかを推奨したいのだけど、この文書の想定読者にはちょっとレベルが高いので……。

とりあえず「まずは、自分が使い慣れている言語で書かれた『アルゴリズムとデータ構造』の入門書を買って読んで手を動かしましょう」とだけ言っておく。

私の場合だと、最初に正式に触れた言語がJavaだったのと、職業プログラマになってからC言語ガリガリとコードを書いてきたこともあって、キャリアの初期には以下の2冊にお世話になった。

定本 Cプログラマのためのアルゴリズムとデータ構造 (SOFTBANK BOOKS)

定本 Cプログラマのためのアルゴリズムとデータ構造 (SOFTBANK BOOKS)

定本Javaプログラマのためのアルゴリズムとデータ構造

定本Javaプログラマのためのアルゴリズムとデータ構造

注意点として、この手の入門書に出てくる初歩的なアルゴリズムやデータ構造は、現実のプログラミングにおいては「よく使われるから言語機能ないしライブラリに用意されている」か「あえて使うメリットが薄いから用意なんてされていない」であることが多い*8。ある程度高度なアルゴリズム・データ構造でもなければ、プログラマが自作する機会は少ない。*9

ただ、自作するにもライブラリを使うにも、そのアルゴリズムなりデータ構造なりの特性を理解する必要があるし、正しく理解するための第一歩として計算量というかO(オーダー)記法に慣れる必要がある。安定である必要があるのに標準ライブラリのクイックソートのルーチンを使ってしまったら台無しだし、O記法が分からないとvectorに代わる(解こうとしている問題に)より相応しいデータ構造をSTLから選び出せないかもしれない。

慣れるための第一歩としての「初歩的なアルゴリズムやデータ構造の入門書」を、私は否定しない。いずれ、必要に応じて次のステップに移るべきだとは思うけどね。

アルゴリズムとデータ構造の扱いにおいて注意すべきことがある。それは「ライブラリが用意されているか否か」だ。これによってアルゴリズムとデータ構造に対するアプローチが少し変わってくる。

まず、採用を考えているアルゴリズムやデータ構造がライブラリ等になく、自前で実装しなくてはならない場合には、ロブ・パイクの "Notes on Programming in C" のルール2〜4に従うべきだ。

Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.

Rule 3. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.) For example, binary trees are always faster than splay trees for workaday problems.

Rule 4. Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures.

http://www.lysator.liu.se/c/pikestyle.html

凝ったアルゴリズムの実装は難しく、バグを入れ込みやすい。それに凝ったアルゴリズムはデータ量が大きい場合に効果がある反面、データ量が少ない場合にはかえって遅くなるもので、そして往々にしてデータ量は少ないものだ。だから、実際に計測した結果、(バグのリスクを負ってでも)本当に必要であると分かるまでは、シンプルなアルゴリズム・データ構造を使うべきだ。

一方で、採用を考えているアルゴリズムやデータ構造がライブラリとして用意されている場合はどうだろうか?

こちらも計測は必要であるし、データ量を勘案しなくてはならない点も同じだ。しかし、採用の可否を検討する際に「バグのリスク」は低く見積もってもよいだろう。ライブラリは(特に言語処理系に付属の標準ライブラリは)十二分にテストされているだろうし、多数の人が使ってきた実績があるだろうからだ。つまり、ルール4は低めに見積もってもよい可能性が高い。

リファクタリング』と『レガシーコード改善ガイド』

職業プログラマのお仕事は、全く新規にコードを書くだけではない。既存のコードベースに手を加えることも多い。なので、既存のコードとの付き合い方も考えなければならない。

……リファクタリングですな、余りにも汚いなら。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

白状しておくと、先にも書いたように、私はどちらかと言えば組み込み系のCプログラマなので、『リファクタリング』と『レガシーコード改善ガイド』はところどころ読んだだけだ。オブジェクト指向プログラミングとは縁遠いのて――メソッドのリファクタリングとか、参考になる部分もあるので、全く読んでいない訳ではないのだけど。

一方で、品質の要求が高いこと、コードベースの寿命が長いこと、ミドルウェア・ライブラリというドライバやファームウェアより一つ上の階層にいることより、関数単位での開発者テストは毎度実施するし、3分の1ぐらいはテストを自動化している。意外とリファクタリングをしやすい環境にいるのだ。変則的だけど「リファクタリングした上で機能追加」というアプローチも多い。

――という程度には、オブジェクト指向プログラミングと縁遠くてもリファクタリングにまつわる知識は重要なので、好き嫌いせず読んだ方がよいっす。

『達人プログラマー

『プログラミング作法』がコンストラクションでとるべき所作をまとめた作法本なら、『達人プログラマー』はコンストラクションの王道を説いた兵法書といったところ。

どちらもキャリアの初期から愛読すべき一冊ですな。

新装版 達人プログラマー 職人から名匠への道

新装版 達人プログラマー 職人から名匠への道

今なら新装版がオススメ。旧版も悪くはないけど、例えば新装版はツール類や言語が最近のものにアップデートされているらしいので、今からキャリアを築こうとする人や、最近この道を進み始めた人は新装版の方がまだとっつきやすいはず。

『達人プログラマー』は『プログラミング作法』よりも少しだけ抽象度の高い内容が書かれている。とはいえ、どちらもコンストラクションに根ざした内容ばかりだ。先輩プログラマからの「ああすればよい」「こうすれば効率的」といった実践的な助言集だと思えばよいかな。

この手の情報は、「職場という閉じた空間」では内容の良し悪しが構成メンバーの力量に左右されやすい。時に古い内容や、時に誤った内容が伝授されてしまう危険がある。

なので、密室に閉じこもるのではなく、せめて「書籍」という形でもよいので外の知識を参照した方がよい訳で。その上で、余裕があるなら布教を……。

『プロダクティブ・プログラマ

つくづく実感するのが、プログラマは怠惰が短気を背負って歩いている不遜な輩であるという事実だ。

実際のところ、例えばプログラマは毎月1回Excelシートに毎度同じような情報を入力する作業が面倒すぎて耐えられない。前月のシートから内容をコピペするのも、それ以前に前月のシートをコピーして当月のシートにすることからして、作業開始直後に発狂してしまうほどに耐性がない。

だから、VBAVBScriptJScriptPowerShellやその他COMを叩けるスクリプト言語を学んで、徹夜してでもツールを自作して作業を自動化してしまうのである。

……うん、何の論理的破綻もみられない、完璧な理論武装だ。

基幹業務の何割かを情報システムで自動化してきた人が、自分たちの作業を全く自動化しないだなんて、狂気の沙汰以外の何物でもないよね。

ということで、プログラマとしてより生産的になるためにも『プロダクティブ・プログラマ』を読むこと。

プロダクティブ・プログラマ -プログラマのための生産性向上術 (THEORY/IN/PRACTICE)

プロダクティブ・プログラマ -プログラマのための生産性向上術 (THEORY/IN/PRACTICE)

本書前半の「技法編」に出てくる個々のツールには、今となっては時代遅れなもの(本書は8年前の本なので)や、業務内容的にそぐわないもの(iOSアプリをEclipseで開発するのは、プログラマ的にも「酔狂」に分類される所業だ)もあるので、注意が必要だ。だけど、「なぜ、そのツールを使うのか?」や「そのツールから何を得られることを期待しているか?」といった背景部分は今でも変わらず通用するので、そこを理解した上で代替を探すようにすること。

デバッグの理論と実践』

書きたてホヤホヤのソースコードにはバグがあるもので、試しに少し動かしてみただけで変な振る舞いを見つけることもあれば、ソフトウェア・テストでいぶり出されることもある。

そういう怪しい部分を見つけたら、デバッグだ。問題が起きている部分を特定し、その箇所で問題が起こる原因を調査・特定し、外部要因その他を勘案して修正方針を決定し、修正し、テストして「バグが修正されていること」と「新たなバグを作り込んでいないこと」を検証する。

デバッグは非常に重要なものの、設計・実装・テストよりも属人性が強いためか、あまり書籍などで語られることのない領域だ。どちらかといえば、プロジェクトの現場にて先輩から後輩に伝授される系の技術であることが多い。

そんな中、『デバッグの理論と実践』はほぼ唯一の、科学的な手法にもとづくデバッグの戦略について書かれた本だ。

デバッグの理論と実践 ―なぜプログラムはうまく動かないのか

デバッグの理論と実践 ―なぜプログラムはうまく動かないのか

デバッグは「仮説と検証」の繰り返しだ。個々の仮説の内容や検証の方法はコンテキストへの依存性が強いものの、仮説を立てる時や検証の際の指針というメタ視点では、この本で語られている戦略は非常に有用だ。

『ソフトウェア・テストの技法 第2版』

コンストラクションの締めに、ソフトウェア・テストの本。

テスト担当じゃなくても、コードを書いたら開発者テストは必要だ*10。書きっぱなしは悪い文化――いや冗談じゃなくて本当に。

見た目は正常に動作してそうでも、裏で問題が進行していたり、ちょっと周辺環境が変わると問題が表面化するような、「たまたま、偶然、それっぽい感じに動いていただけ」というケースは多いし、そのようなケースは「テスト担当によるシステムテスト」では発覚しにくいものだ。

だから、そのコードに一番詳しいだろう「書いた本人」が、出来立てほやほやのコードを、ハンマー片手に創造的に破壊しなくてはならない。それが開発者テストだ。そのためにも、テスト担当じゃなくともソフトウェア・テストについて学ぶ必要がある。

また同時に、ソフトウェア・テストに詳しくなるということは、テストにて注目すべき頻出事項――すなわち「よくバグを作り込んでしまう部分」に詳しくなることでもある。なので、ソースコードを漫然と記述するのではなく、ミスしがちな部分に最新の注意を払うようになることで、最初からバグを作り込んでしまう可能性を低くする効果も得られる(もちろん個人差はあるけど)。

個々の技法を除けば、ソフトウェア・テストの真髄は『ソフトウェア・テストの技法』にまとまっていると思う。

ソフトウェア・テストの技法 第2版

ソフトウェア・テストの技法 第2版

  • 作者: J.マイヤーズ,M.トーマス,T.バジェット,C.サンドラー,Glenford J. Myers,Todd M. Thomas,Tom Badgett,Corey Sandler,長尾真,松尾正信
  • 出版社/メーカー: 近代科学社
  • 発売日: 2006/08/01
  • メディア: 単行本
  • 購入: 7人 クリック: 267回
  • この商品を含むブログ (47件) を見る
せめて「第1章 自己診断テスト」だけでも読んで、打ちのめされなさい。いや本当に、良いテストケースを考えるのは難しいのよね。

『人月の神話』

コンストラクションについて一巡りしたところで、職業プログラマの基礎教養として、ソフトウェア工学とプロジェクト管理についての古典かつバイブル*11の『人月の神話』を読もう。

あ、原書発行20周年記念増補版ないしそれの新装版がお勧め。

人月の神話【新装版】

人月の神話【新装版】

下っ端プログラマもプロジェクトの成員なので、大規模ソフトウェア開発がどういった点で難しいかについての知識は仕入れておいた方が良い。じゃないと「後から追加で増員の増員」なんて話をもろ手を挙げて賛成しちゃいかねないよ。

なお、このページで推奨されているように、この本は最初から順に読むのではなく:

  1. 18章(著者自身による1〜15章の抄訳:1975年時点の見解)
  2. 16章(1986年時点の見解)
  3. 17章(1995年時点の見解)
  4. 19章(1995年時点の見解)
  5. 1〜15章のうち、気になったところ

――という順序で読むと結構楽だ。その情報、10年前に聞きたかった。

『アンダースタンディングコンピュテーション』

ここまで実務寄りの本ばかりだったので、ここで理論寄りの本を1冊。

理論計算機科学という計算機を理論的に研究する分野の中に、計算理論という「じゃあ『計算』って何なの?」とかそういうことを理論的に研究する学問がある。

その計算理論を齧る本として『アンダースタンディングコンピュテーション』を読んでおくといいことがあるかも。

忘れがちだけど、コンピュータって2進数の計算機なわけだ。たまたま、「情報」という形のない代物を2進数の数値で表現できることに気づいた天才がいたおかげで、「計算によって情報を生成・加工できる!」ということで情報処理に使われるようになったけど、結局は計算機だ。

だから、計算理論にて「理論上は可能」と判明したことは、現実のコンピュータでも可能である可能性が高いし*12、「理論上不可能」なら現実のコンピュータでも不可能だ。

それと、計算理論では計算モデル(コンピュータの数理モデル)を定義して考察するのだけど、計算モデルの中には有限オートマトンのように普通にプログラミングで用いられるものも多い。だから、例えば状態遷移図/状態遷移表を用いて設計する場合には、有限オートマトンの可能性と限界ぐらいの知識はかじっておいた方が良い。でないと、有限オートマトンでは無理がある問題を状態遷移図で設計しようとして破綻をきたすかもしれない。

可・不可の見極めのツールとして使える計算理論は、プログラマが齧っておいて損はないのだけど、数学やコンピュータサイエンスの下地がないプログラマが独習するには難しい分野でもある。

そんな中、「数学的な厳密さ」よりも「概念の学びやすさ」を重視したこの本は、下地のない文系プログラマでもなんとか計算理論の初歩を学べるかもしれない最後の砦だ。

『詳説 正規表現 第3版』と『正規表現クックブック』、時々『sed & awk デスクトップリファレンス』

商品知識になるけど、正規表現の本を挙げておこう。

正規表現は意外と使い勝手が良いツールだ。開発するソフトウェアにて正規表現を直接記述する人はもちろん、そうじゃない人も、例えばコーディング中に正規表現を使って検索・置換をするとか、開発者用の内製ツールを実装する時に正規表現を使うとか、正規表現を用いることで作業の効率化を推し進められる余地があるものだ。

だから、あえて正規表現の本も挙げようと思う。組み込みプログラマだって正規表現の1つや2つ使うものですよ。

正規表現については、ガッツリ学ぶための本と、実際に正規表現を書く際に便利なクックブック系の本を併用すると効果的だ。

ガッツリ学ぶための本としては、『詳説 正規表現 第3版』が鉄板だ。ガッツリすぎてゲップが出そうなほど正規表現やその実装について解説している。

詳説 正規表現 第3版

詳説 正規表現 第3版

クックブック系の本は色々あるけど、正規表現は意外と方言が多いので、主要7言語の正規表現を網羅している『正規表現クックブック』を推奨したい。実際、便利だし。

正規表現クックブック

正規表現クックブック

おまけとして、awkgrepsed・viあたりのツールを多用するようになった暁には、これらで使われる正規表現の方言が一覧化されている、この本もどうぞ。

sed & awk デスクトップリファレンス

sed & awk デスクトップリファレンス

伝統的なUnixツールの正規表現は『正規表現クックブック』から漏れているので、代わりにこちらの本を使うこと。

『マスタリングTCP/IP 入門編 第5版』

もう一つ商品知識として、今やインフラ化しているTCP/IPの基礎本も挙げておこう。

マスタリングTCP/IP 入門編 第5版

マスタリングTCP/IP 入門編 第5版

データベースも「SQLiteを組み込んだスマホアプリ」のように使用領域が広がりつつあるものの、ネットワーク機能が組み込まれたシステムはもっと多い。組み込み機器でも、IoTというバズワードがあるぐらいで、例えデータベースは搭載してなくともプロトコル・スタックは搭載していたりするものだ。

コンシューマ向けの多機能機器では「USB・BLE・WiFi」の御三家が欠かせない。有線LANのポートを持つ情報家電も多い。クラウドサービス花盛り。企業の社内システムもWebベース化し始めて久しい。あと、デスクトップアプリケーションが自動更新機能を持つようになってから何年経ったのだろう。

こうなってくると、インフラ・ネットワーク系以外の開発者もTCP/IPと無縁ではいられない。どうしても、何かしらの通信を行うソフトウェアを書くことになる。

もちろん、通信ソフトウェアといっても多種多様だ。組み込み機器とWebアプリでは、それぞれ学ぶべき内容は異なる。でも根っ子の部分である「TCP/IPの基礎」はどちらも同じなので、とりあえず『マスタリングTCP/IP 入門編』ぐらいは読んでおくべきだ。そして階層を意識せよ。

通信ソフトウェアのテスト・デバッグと、社内ネットワーク管理者トラブルシューティングは、紙一重の部分がある。どちらもプロトコル階層を意識して問題を切り分けることが肝要だ。

『Webを支える技術』か『オンラインゲームを支える技術』、もしくは両方

引き続き、商品知識系TCP/IP派の本。この項は、もう少しTCP/IPに深入りするかもしれない人向けの内容なので、不要なら無視しても構わない。

これは私の独断と偏見なのだけど、TCP/IPを土台として何らかのサービスを構築する人は、大雑把に2つに分けることができる。

1つは、従来の「Webサービス・Webアプリケーション」のコンテキストないしその延長線上にいる人。HTTP・HTML・JavaScriptを土台として、RESTアーキテクチャなどでシステムを構成するものだ。

そういう方面に縁がある人は、基礎教養として『Webを支える技術』を読むべきだ。

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

組み込み開発者でも、機器のWeb管理コンソールを作るような場合には、本書の知見が参考となる(というか周囲にWebアプリの開発者とかがいなくて、本書で独学するしかなかったりするものだけど)。

もう1つは、リアルタイム性の高いシステムをWeb上に構築しようとする人。MORPG/MMORPGのようなゲームや、サウンドや映像をリアルタイム配信するシステムなどだ。

リアルタイム性を追及すると、どうしてもTCPではなくUDPベースでの通信となり、パケットロスをどうするか考えざるをえなくなる。性能向上のためNAT traversalでP2Pを実現するべく四苦八苦することもある。サーバサイドではデータをオンメモリで保持して、データベースの読み書きを減らす工夫が必要になるかもしれない。何より、性能を求めるあまり「サーバサイドをCやC++で実装する」という魔境かもしれない。

――と、まあ一般的なWebシステムとは毛色が違う世界もあるわけで、そっち方面に進みそうなら、『オンラインゲームを支える技術』は結構参考となる。というかこの本以外に思いつかないんだな、これが。

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

ちなみに、リアルタイム性の高いシステムを構築したい人的には、無線通信と「モバイル端末の賢いバッテリー制御」は鬼門だ。無線はパケットロスやジッターとの戦いが激化するし、「賢いバッテリー制御」のおかげで通信モジュールのOFF/ONに巻き込まれてジッターが発生する(例えばWiFiモジュールがONになるまでアクセスポイントにてパケットが待たされるとか)などの問題が起きることがあるからだ。

だから有線LAN非搭載のPCとか止めてほしいなあ……将来、USB 4.xとか5.xとかの世代で直接Ethernetに接続できるようになるとか、そういう方向で生き残ってくれないだろうか。無理かなあ。

『インタフェースデザインの心理学』と『続・インタフェースデザインの心理学』

最後の締めとして、今までに挙げてきた本からすると変り種かもしれないけど、『インタフェースデザインの心理学』とその続編を挙げよう。

インタフェースデザインの心理学 ―ウェブやアプリに新たな視点をもたらす100の指針

インタフェースデザインの心理学 ―ウェブやアプリに新たな視点をもたらす100の指針

続・インタフェースデザインの心理学 ─ウェブやアプリに新たな視点をもたらす+100の指針

続・インタフェースデザインの心理学 ─ウェブやアプリに新たな視点をもたらす+100の指針

書名からUIやUX関連の本のように感じるけど、実際はヒトの認知の仕方や感じ方、注意の向け方などについて紹介している心理学の本だ。

なぜ、この本を挙げるのか? プログラミングという行為が本質的に難しいからだ。

本質的に難しい物事に取り組むとき、その物事に付随する偶有的(非本質的)な諸々まで難しかったら、正直やってられない。なので、まずは偶有的な諸々の部分の難しさを緩和する必要がある。コンピューティングの世界では、偶有的な部分の難しさを緩和するためにあらゆる手段*13がとられている。ヒトの認知の特性を学ぶのもその1つだ――プログラミングをするのは人間だからだ。

例えば、職業プログラマの書いたソースコードは、他人や数年後の自分に読まれるものだ。可読性の良し悪しについて考えるとき、ヒトの認知の特性も考慮するべきなのだ。

だから、例え言語仕様で許されていようとも、基本的には個々の識別子を空白(スペース)で区切るべきだし、関連性の高いステートメントは隣接させつつ、関連性の低いステートメントの間には空白行を入れるべきだ。同時に、関数・メソッドといった「比較的関連性の高いステートメントの集合」の中に、無造作に2〜3行もの連続する空白行を入れるような暴挙は慎むべきだ。

――こういう細かい話も、掘り下げていくとヒトの認知の仕方が関連しているものだ。

まあそれだけではなく、アプリケーションの画面構成やWebアプリのデザインを考える時や、大勢の人の前で話すときに注目してもらう工夫など、いくつかのシチュエーションで参考となるネタも書かれている。UIやUXのデザインでも参考となる一冊だ。

――要するに、UIやUXをデザインする時の視点は、プログラマ間のコミュニケーションで用いられる「ソースコード」という特殊なインタフェースにも流用可能である、というだけなのだけどね。本書は認知心理学とかのネタが多いので、応用が効くのだ。

まとめ

7冊とか10冊にまとめられなかったのは、ひとえに私の不徳の致すところであります。

まあ、情報系の課程を進みつつ趣味でガリガリとコードを書いていた人とは、スタート時点でそれなりに差があるわけだ。だから、その差の分だけリストに挙げられた本が増えていると思ってほしい。

*1:定番書でも、難易度ないし価格的に省いたものもある。

*2:知らない人向けに書いておくと、この本の作者はUnixの開発に多大な貢献をした人で、ミニ言語であるAWKの共同開発者で、プログラマ向けの古典ともいえる名著を何冊か共著で出している人で、コンピュータサイエンスの教授である。少なくとも、古参のC言語使いや、Unix界隈の古くからの住人の間では有名な人だ。

*3:設計といっても、教科書でいう「詳細設計」の局面の話だ。

*4:ワーニエ法については記載なし。

*5:『ソフトウェアの複合/構造化設計』には載っていないけど、重宝する技法だ。

*6:このタイトル、日本語訳の際に付けられたのではなく、原書が "Algorithms + Data Structures = Programs" なのである。なお新訳版は『アルゴリズムとデータ構造』というタイトルだが、こちらの原書は "Algorithms + Data Structures" である。

*7:付け加えると、「モジュール」や「クラス」は他のパーツと組み合わせて使われるものなので、インタフェースも重要となってくる。

*8:ただし組み込み系のCプログラマを除く。

*9:例外は二分探索かな? ログファイルのような「ソート済みのファイル」を検索する需要は意外とあると思うのだけど、標準ライブラリの二分探索ルーチンはオンメモリのデータが対象だから……。

*10:もっとも「開発者テストを実施するプロジェクトか否か」という点は、また別の問題である。まあ、組み込み開発のように高品質なソフトウェアが求められるプロジェクトでは必須だろうけど。

*11:なお、「名前は知ってるけど読んでない」とか「読んだけど実践していない」という点でもバイブル(聖書)並みらしい……。

*12:ただし現実のコンピュータには「物理的制約」があるわけで、例えば理論上は可能だけど現在のコンピュータでは数万年かかるとか、全世界のコンピュータのメモリをかき集めても足りないとか、そういう理由で「現実的ではない」ということもある。

*13:高水準言語、特定用途向けのDSL、再利用可能なライブラリやフレームワーク統合開発環境、高速な開発マシンと広いディスプレイ、その他。