memorandums

日々の作業ログです。

基本情報(午後)Javaの感想

オブジェクト指向分析設計という2年次の科目を今年から担当することになり、目標をどこに設定するかを検討したときに、基本情報技術者試験の午後の問題を参考にしました。これが解けるくらい(解けないまでも挑戦してみようと思うくらい)にJavaの応用には慣れさせたい。。。ということがわかりました。

過去問を5年分ほど読んでみましたが、Javaが導入された当初はオブジェクト指向らしくない(失礼しました!)問題がありましたが、近年はコレクションクラスやスレッドを使った、それなりにJavaを使った経験がないと解けなさそうな問題がありました。

特に今年の春の問題はコレクションクラス(ジェネリクス、拡張for文など)が多用され、本学科で採用している教科書ではちょっと対応が難しい問題もありました。

で、昨日行われた問題が気になったので読んでみました。

Link: 平成24年度秋期試験(1) 問題冊子・配点割合・解答例・採点講評(PDF)

一応、自分で解いてみました。その感想を少し残しておきたいと思います。

スレッドに関する問題でした。秋はコレクションクラスに関する出題はありませんでした。。。春のできが悪かったのでしょうか?

オッチョコチョイの性格が災いして。。。恥ずかしながら1つひっかかって間違えてしまいましたが、その他は問題ありませんでした。


設問1のa

これはaの条件がtrueになるまでループします。Timerクラスのコンストラクタの第3引数で指定したdelay秒待機する条件をセットします。プログラム的にはendAtがタイマーの終了時刻ですので、endAtがcurrentTime()より大きい間はループさせることになります。答えはエになります。落ち着けば1年次の授業範囲でも十分に対応できる問題だと思います。

設問1のb

こちらはプログラムの説明の(1)の⑤(e)に対応します。ただ、ちょっと読み解くのは1年次の範囲では難しいかもしれません。仕組みは以下の通りになります。スレッドをキャンセルするためにTimerクラスのcancelメソッドを呼び出すと、Workerクラスのcancelメソッドがコールされます。そこではcanceled変数をtrueとして実行中のthreadインスタンスに対してinterruptメソッドを呼び出します。interruptメソッドを実行するとそのスレッドでInterruptedExceptionが発生します(仕様)。そこで選択肢bのプログラムに到着します。スレッドをCancelすると何をするのか。。。(1)の⑤(e)の後半部を実装する必要がありますが、それは次のブロック(if (canceled)以下)に書かれています。選択肢bの場所では割り込みを検知したときにwhileループを抜け出せばいいことがわかりますのでbreakしかありません。interruptメソッドの仕様を理解していないとわからないか。。。というとそうでもないと思います。ループを抜けることだけ考えてもbreakという答えは導き出せると思います。

設問1のc, d

cはTimerActionがinterfaceですのでimplementsしかありません。ありがたく頂戴しましょう。dもかなり楽な問題です(プログラムを読まなくていいという意味で)。dの前がメソッド名。後ろが例外名。となるとthrowかthrowsしかありません。この辺は1年次でもやっていますね、確か。あとはサイコロを振って。。。(笑) 体と目で憶えるか。。。あとは英語の知識で憶えるか?僕の勝手な解釈ですが、メソッド名 throws 例外名を英語的に考えると(もともと英語ですやん)、主語 throws 例外名となり、主語であるメソッドは意味的な例外はあるかもしれませんが三人称単数と考えて「s」をつける。逆に例外を投げるthrowは命令形と考えると「s」はつけない。なんていう憶え方があるかもしれません。単なる思いつきですが。

設問1のe

こはちょっと難しかったです。ちょっと考えました。ただ選択肢には迷うような要素がないので素直な問題と思います。createTimerの第2引数はTimerActionなのでTimerActionインタフェースを実装したクラスのインスタンスがくるべきです。このプログラム中にはTimerTestクラスしかありません。ただ。。。newしているところがない(ように一見みえます)。。。ここがちょっと難しい。TimerTestクラスはTimerActionインタフェースの実装クラスでありテストクラスでもあるので見つけ難くなっているのではないかと思います。解答群をみると明示的にはエのnew TimerAction()くらいしかありませんがinterfaceはそのままではインスタンス化できません。となるとthisしかない。thisは何かというとTimerTestクラスがインスタンス化されたときの自分自身を差します。longerTimerにはlongerTimer自身、shortTimerにはshortTimer自身を入れる。。。thisでいいですね。thisの使い方に慣れていないとちょっと難しい問題だと思います。

設問1のf

これは簡単。仕様が58ページの中段くらいに書かれていますね。「メソッドonAlarmが、shortTimerを引数として呼び出された場合、longTimerのタイマ処理をキャンセルする」と。onAlarmの第1引数のtimerには所定の時間が経過したインスタンスが格納されています。そのインスタンスとshortTimerを比較すれば、そのインスタンスがshortTimerかどうか確認することができます。longTimerをキャンセルするには。。。上記のbのところで解説した流れにそって考えるとキャンセルしたいスレッドに対してcancelメソッドをコールするしかありません。僕は早とちりしてイと答えてしまいました。いかんですなぁ。。。>自分

設問2

これはちょっと迷います。ポイントはThread.currentThread().getName()の結果であり、Thread.currentThread().getName()はTimerクラスで定義されているgetName()メソッドじゃないのか。。。と早とちりしてしまう危険性もあります。落ち着いてソースを読んでみるとcurrentThread()というくらいですから現在実行中のスレッドが戻り値に入ることは想像がつきます。Threadクラスをnewしている箇所が1つあります。そこの第2引数にgetThreadSequenceName()が指定されています。このメソッドはTimer-0, Timer-1,...という文字列を返すメソッドです。この第2引数とThreadインスタンスに対するgetName()が結びつくかどうか。。。日常的にこの辺を触っている人にはわけない問題ですが、そうでない人にとってはちょっと考え込むはずです。オンラインドキュメントを試験中に見ることができればわけないのですけどね。。。ちなみにドキュメントはこちらです。確かに第2引数に名前をセットすることができ、それをgetName()メソッドで取り出すことができる仕様になっています。ということで、キしかないことがわかります。


まぁ、実際の試験では時間はあまりかけられないでしょうし、ぱっと見で勝負しなければならないこともあると思います。確かスレッドは過去にも出題されたことがあると思います。コレクションクラス、スレッドはある程度網羅的にメソッドを利用しておかないとJavaを選択するのは難しそうですね。スレッドやコレクションクラスも大切だと思いますが、継承や委譲などを読み取れるか。。。というあたりの設問、リファクタリングすべきメソッドと対処例の選択とか、そういう系の問題もありなのかとも思いました。基本情報はITSSのレベル2であり”「上位者の指導の下に」業務を遂行するために必要となる知識や技能”をいうということですから、実務的には先輩が書いた設計書を読んで、それを(マニュアル等を読みながら)実装できる者かどうか、というところが基準だと思います。そう考えると設計書から設計意図を読んでプログラムに展開するところ、自分で作ったプログラムを自分で見直す能力を検査してもいいかな。。。と勝手に思ったりします。