正しい基本情報技術者試験の勉強法

プログラマ(というか開発者)にとって基本情報技術者応用情報技術者ソフトウェア開発技術者)の試験は割合とネタになりやすい話題だと思う――主に役に立つ/役に立たないという観点で。

コの業界では「この手の資格は役に立たない」と主張する人も多いようだけど、私自身はこう考えている。

  1. 技術的な方面で色々とやってみたいのなら、
  2. やりようによってはそこそこ役に立つ。
  3. 但し即効性はないし、内容は比較的保守的(最新技術より枯れた技術*1。温故知新)。
  4. あと費用対効果の観点では検討していない。

注意すべきなのは2番目の項目で、乱暴に言ってしまえば勉強の仕方を間違えたら全く役に立たない。費用対効果でみれば「大赤字だけど全く効果なし」という悲しい結果に終わってしまう。

基本情報技術者を受ける人で「技術的な方面で色々とやってみたい」という志を持つ人は、プログラマに始まる開発者か、又はそういう立場を目指している学生だろう。ならば実際に開発する際に何かしら流用できるように基本情報技術者試験応用情報技術者試験の勉強をしておくべきだ。

費用対効果については分からないが、情報系の学生なら就職活動絡みで受験することになるだろう。新入社員も会社によっては受験させられるか、強制はされないけど何となく受験した方がよさそうな空気が漂っているかもしれない。どうせ受験するのなら後で活用できるような勉強をしておけば費やした時間は無駄にならない。文句を言うよりは建設的だ。

ではどう勉強すればよいのだろうか?

この門をくぐる者は一切の希望(合格)を捨てよ

「合格したい」という欲求は全ての妨げとなる。煩悩を捨てて心安らかに勉強することが肝要だ。

合格しようという気持ちが強いと、どうしても学習内容が試験問題の傾向と対策やら過去問やらに偏っていく。しかしそれらの内容は基本情報技術者応用情報技術者の試験に特化したものだ。極めても「試験」に通じた人にしかなれない。現実の開発とは少しばかり方向が違うのだ。

この極端なバージョンが「過去問等の問題集をひたすら解く」という勉強法で、この方法の実践者は今までの試験の内容に通じた人になれるので、今までと同じような試験内容なら合格する可能性が高くなる。その反面、出題される問題が入れ替わったりした場合には合格する可能性は落ちるのだが*2

どちらにしろ、そんな勉強をしたところで実際の開発に流用できる部分がどれほどあるというのか? 何より2〜3ヵ月後に内容を覚えているだろうか?

個人的には、コの業界で「基本情報技術者なんて役に立たない」と噂される原因はこの勉強法にあると考えている。だから私は試験が役に立たないとは言わない。勉強法が間違っているのだ。

問題集は捨てる方向で

前項に基づいて、問題集は買わないこと。Web上の過去問も試験間際になるまで見るべきではない。

試験に特化した勉強ばかりすることは悪だ。ならばどう勉強するか?

  1. 問題集ではなく教本の類を買う。それも出題される問題の背景となる部分の解説がキッチリ書かれているやつ。
  2. 問題3割、解説7割ぐらいの配分で勉強する。解説部分の理解、仕組みの把握を重視。解説の裏を読みとるべし。
  3. あと手を動かす。教本に書かれている知識や理論を実践に移すことで、現実の技術/開発と結びつけて考えられるようにする。

これに尽きる。極端な話、問題集は不要だ*3

学習期間は長めに設定

独学で基本情報技術者試験を受ける場合、よく引き合いに出される学習期間は半年〜1年ぐらいのように思う。

が、仕組みの理解と把握を重視する以上、少なくとも2〜3年は見積もっておくべきだ。情報系の学部なり専門学校のカリキュラムをキッチリ理解しようとあがくと、短くともそれぐらいは必要ではないだろうか。

ちなみにこれは「2〜3年経たないと受験できない」という訳ではない。

参考資料を買い込んで読め

解説部分の理解を重視して取り組むと、どうしても教本だけでは足りなくなる。なので副読本として参考資料を買って読むべきだ。

例えばもし数値の内部表現について学習しているなら、調子に乗って『Write Great Code〈Vol.1〉ハードウェアを知り、ソフトウェアを書く』に手を出してもよいだろう。

データ構造やアルゴリズムについて学習するなら『定本Javaプログラマのためのアルゴリズムとデータ構造』などの入門書を読みつつサンプルコードを写経して動かしたり改造して遊んだりしてみるべきだ。というか改造しろ。で、コードを読みながら頭の中で状態の変化をトレースするべき。グラフのアルゴリズムの勉強を兼ねて*4人材獲得作戦・4 試験問題ほか: 人生を書き換える者すらいた。に挑戦するのも良いかもしれない(それなりに自信がある人限定)。

コンピュータの構成要素について学習しようと思うのなら『コンピュータの構成と設計 第4版 上 (Computer Organization and Design: The Hardware/Software Interface, Fourth Edition)』を買うのも一つの手だ。『コンピュータアーキテクチャのエッセンス (IT Architects Archiveシリーズ)』も捨てがたい。『CODE コードから見たコンピュータのからくり』なんて論理回路も絡めた有機的な繋がりを机上で体験できるので太鼓判を押したくなる。

ソフトウェアの設計手法についての学習に差し掛かったなら、『ソフトウェアの複合/構造化設計』のような構造化設計の古典や『組込みソフトウェア開発のための構造化モデリング 要求定義/分析/設計からソースコード作成までソフトウェア開発上流工程の基本を構造化手法に学ぶ』のような教科書を併読するべきだ。オブジェクト指向に関しては既に先人がリストを挙げているので割愛*5。コードを書ける人ならテストプロジェクトを立ち上げて実際に書くコードに学習内容を反映させるべく七転八倒した方がよい。

ネットワークに関しては『マスタリングTCP/IP 入門編 第4版』は外せない。

プログラミング言語問題の対策では、できれば試験に特化した入門書は避けて、その言語のプロが良書だと紹介している入門書に手を出した方がよい。ちなみにC言語に手を出すのなら入門書以外に4〜5冊は必要だと心得るべし*6

教本が無味乾燥に感じられてきたら『痛快!コンピュータ学 (集英社文庫)』でも読んで一休みだ。

手を動かせ

教本や参考資料を読むだけでなく、勉強した内容を吐き出すことも重要だ。

例えば基本情報技術者試験だとプログラミング言語問題がある。なので言語の勉強をすることになり、十中八九処理系を入れてコードを書いて動かすことになると思う。

この時、その言語の入門書を片手にサンプルコードを打ち込んで動かすだけでなく、例えばアルゴリズムとデータ構造の本のコードを打ち込んで動かしてみたり、サンプルコードを改造してみたり、既存のちょっとしたツールを真似て自作してみたりするべきだ。

C言語Javaを選択するのなら『プログラミング作法』あたりも副読本にするべきだ。ネットワークの勉強を兼ねてソケットプログラミングするのもよい。HTTP専用のwgetもどきをLinux上でC言語で書けば、システムコールを通じてOSの勉強にも役立つ。

ハードウェア寄りの世界に興味があるのならC言語と平行してCASLアセンブラの雰囲気を味わうのも悪くない。マルチスレッドのデータ競合の問題などは、アセンブラレベルで考えると納得しやすいものがある。

コードは漫然と書くのではなく、できる限り座学の内容を吐き出すべきだ。構造化設計の項目を学習したのならモジュール強度・結合度あたりを念頭において関数やメソッドを書くべき*7だし、オブジェクト指向プログラミングの項なら最低限Javaなどで各種技法を使ってみるべきだ――実用的なツールを作る際にC言語を使うのなら学習したアルゴリズムやデータ構造を採用して小ツールを実装するのもよい。オートマトンや状態遷移は実際の開発にて設計や実装で意外と重宝するので、まずはパーサの類の実装で試してみてはどうだろうか。

そうそう、言語の選択では「表計算のみ/CASLのみ/表計算CASL」の組み合わせだけは止めておけ。実際に仕事で使う可能性が高いC言語 or Java or COBOL一択か、それらの言語と平行して表計算ないしCASLを勉強するべき。学生で授業/講義でそれらの言語を勉強していて多少暇があるのなら、0から始めて4ヶ月でJavaCASLを試験を通る程度に仕上げるのは不可能ではない(※効果には個人差があります)*8 *9

データベースの学習では、実際にオープンソースのデータベースを入れてモニタ経由で操作してみるべきだ。ちょっとしたデータベースを作成してみるのが鉄則だろう。

ネットワークの学習では小規模でもよいからLANを組んで複数のマシン間で通信してみた方が分かりやすい。Wiresharkでパケットをキャプチャして眺めるもよし、ソケットプログラミングするもよし。サーバを立てて、スクリプト言語を使ってHTTPなどのテキストベースのプロトコルでやりとりしてみれば、OSI参照モデルの上位3階層の説明の意味が何となく分かってくるものだ。

OSについては『オペレーティングシステム 第3版』あたりを片手にMINIXを動かしながらソースを読むのが最上の学習方法のような気がするけど、そこまでしなくてもPCや仮想マシンLinuxFreeBSDを入れて触りつつ『UNIXカーネルの設計』を読みながらシステムプログラミングをするだけでも随分違うと思う。

ともかく、座学で学んだら関連する現実の技術を触ってみるべきだ。大抵の場合、理論から出発して現実世界で揉みに揉まれて現在の技術となっていたり、その反対に現場*10の経験に基づく暗黙知から出発して紆余曲折を経た果てに抽象化されて知識や理論として教科書にまとめられていたりするものだ*11。なので産学連携ではないが双方の摺合せをしておく必要がある。

あとこれをやっておくと、新人に技術的なことを教える時に「基本情報技術者試験に出てくる用語」という共通言語を使うことができるのだが、それが役に立つかどうか定かではない。

何なら機材も買え

仮想マシンもよいが、無茶苦茶になっても大丈夫なように学習用にPCを1台買って弄るのもよい選択だろう。オープンソースのOSを入れて触るのも良い経験になる。

単に資料で見るだけでなく実物を手にとって触ってみる方が実感が湧く*12ので、個人的にはメーカー製PCやショップブランドPCではなくベアボーンを買うか自作PCに挑戦してみるべきだと思う。

ネットワーク学習ではLANと複数のマシンが必要になる。まあブロードバンドルータを使っていれば大抵は複数の機器を接続できるはずだ。

その他

以上の内容は7割ぐらいネタなので信じないように。

*1:もっとも、分野による違いはあれども大抵の仕事では最新技術よりも枯れた技術の占める割合の方が大きいのだが。

*2:例えば2005年秋の基本情報技術者試験の合格率をその前後数年と比較すること。

*3:ちなみに私の場合、問題集を買ったものの結局は使わなかった。

*4:または再帰でも可。

*5:私はオブジェクト指向が分からない人なので外部に勝手に丸投げ。オブジェクト指向プログラミングという括りなら、抽象データ型にさかのぼって七転八倒した挙句に『まつもとゆきひろ コードの世界?スーパー・プログラマになる14の思考法』を読んで何となく腑に落ちた気になっている。

*6:それなりの品質のコードを書けるようになりたい場合。但し言語に関する部分のみなので、「よいコードを書く」という目的の為には別の本と訓練が必要。

*7:つまり意味もなくグローバル変数やクラス変数、インスタンス変数で一時的なデータを受け渡す奴はモジュール結合度のことを分かっていないのだ。

*8:但しそれは実用レベルでソフトウェアを実装できることを保証しない。

*9:もっともJavaに関しては旧基本情報技術者のプログラミング問題の簡単な方しか解けない程度かもしれない、と経験者として書いておく。まあ初期の頃に比べるとJavaの問題は難しくなっているらしいので、今となっては通用しないのかもしれないが。それを確かめようと2011年度試験用の問題集を立ち読みしてみたのだが、自分自身のレベルが変化していて参考にならなかったorz

*10:といってもその昔は開発者に占める専門家の割合は高かったと思うのだが。

*11:暴論だ……。

*12:もちろんそれは単なる錯覚かもしれないが。