日曜日 1 20, 2008
日曜日 1 20, 2008
Java Puzzler、続いての出題です! 先人の教えを整理すると・・・? では、まず問題のコードを見てみましょう。
登場するクラスは String クラスだけ、という簡単(そう) なコードですね。 さて、このプログラムの結果は以下のどれでしょうか?
ちなみに "Less is more." は「過ぎたるは及ばざるがごとし」、"Time flies."は「光陰矢のごとし」 "Money talks." は「金が物を言う」ということわざです。日本にも外国にも似たような意味のことわざがあったりして、比較するとおもしろいですね。「覆水盆に返らず」と "It is no use crying over spilt milk." は同じ意味ですが、文化の違いがよく出ているなぁ、と感心してしまいます。 それでは、答えはまた次回!
月曜日 1 07, 2008
去年出題した Autoboxing の問題の解答を掲載します! (長い間お待たせしてしまってすみません・・・)
というようなコードでした。さて、このプログラムの結果は以下のどれでしょうか?
という問題でした。わかりましたか? それでは、解答をみていきましょう。
火曜日 11 20, 2007
おまたせいたしました! Sun Tech Days で大好評だった Java Puzzler の問題を少しずつ載せていきたいと思います。 何かと話題のBoxing・・・結果は?
Autoboxing って何だっけ?という方は、以下で復習しておきましょう!
木曜日 4 05, 2007
今回はJava in the Boxでおなじみの櫻庭さんからの出題です。 ボタンを押すとどうなる?次のプログラムを実行して、表示されるボタンを押して、なが〜い処理をしている間、ウインドウの表示はどのようになるでしょうか? public class Monologue implements ActionListener {
そのときウインドウの表示がどのようになっているかを次の中からお選びください。
今週のクイズ(5) 解答編:顔文字 更新が遅れてしまい誠に申し訳ありませんでした m(._.)m なるべく定期的な更新を継続のための努力をしていきますが、しばらくの間は更新が不定期になるかもしれません・・・。さて、解答編のご紹介がおくれてしまった先々週のクイズの解答をご紹介しておきます。まずは問題の復習からです。 顔文字次のプログラムのうち、どのようにメソッドや変数を定義してもエラーとなってしまうのはどのケースでしょうか? switch (face) {
解答
解答はこのプログラムを統合開発環境で表示してみると一目瞭然ですね。
ご覧の通り、答えは4番のようですね。では一つずつ解説していきます。まず、一つ目の
ですが、これは簡単ですね。boolean ToT = true; のような変数をあらかじめ定義しておけばプログラムは問題なく実行されます。T (大文字のティー)も o (小文字のオー)もちゃんとJavaで変数名で利用する事ができるからです。さて次は
です。これはちょっとだめなんじゃ??と、一瞬思うかもしれません。問題を考えるときも一番苦労しました(^^; この選択肢のポイントは次の二つです。
ということです。実は、顔と思っていた部分も分解すると、カタカナの「ミ」という名前の変数と、アルファベット小文字の「v」の排他的論理和の式だった訳です。なのでこれも、boolean ミ = true, v = true; などと事前に定義しておけば無事実行する事ができます。 では3番目を見てみましょう。
これはわりと有名な無限ループの書き方ですね。for文は (開始; 継続条件; 増分) のように記述しますが、開始と増分はこの中に書かなくても良いことになっています。このケースは継続条件のところに 「_」(アンダーバー) という変数を置いて for文を成立させています。アンダーバーもJavaの変数名として有効な文字ですからこれも、boolean _ = true; などと事前に宣言しておけば問題ありません。さて次はエラーとなってしまうケースです。 while (つд⊂) さて、これはなぜエラーとなってしまうのでしょうか。その前にまず1文字ずつ見てみましょう。1文字目はひらがなの「つ」です。先ほど、カタカナがokだったので同様にひらがなも問題ないのは想像に難しくありません。そのつぎの「д」はキリル文字で、アルファベットでいうと D 相当の文字です(参照: Wikipedia)。Javaでは文字は基本的にユニコードで処理されており、国際化されているのでこのようなキリル文字も扱うことができるわけです。 では、それならばなぜ「⊂」はダメなのでしょうか。実は「⊂」は、数学で包含関係を表す記号です。Javaではこのような記号に分類される文字を変数名やメソッド名等の識別子として使う事ができません。このため、どのように変数を事前に定義しておいても「⊂」は不正な文字としてコンパイラによってエラーとされてしまいます。ちなみに、Javaで識別子として利用できる文字はjava.lang.Character#isJavaIdentifierStartメソッド(開始の1文字目)と、java.lang.Character#isJavaIdentifierPartメソッドをつかって調べる事ができます。 さて、ここまでわかればあとの二つは簡単ですね。 ヾ(-_ー) これは、 「ヾ」という濁音付きカタカナの繰り返し記号(KATAKANA VOICED ITERATION MARK)で、これもカタカナと同様Javaの識別子として利用できる文字です。なので、void ヾ(int a) {} のようなメソッドを用意しておけば良い訳です。ちなみに、引数の 「-_ー」は、「-」(マイナス)、「_」(アンダーバー)、「ー」(長音記号)です。アンダーバーも、長音記号も変数名として使えます。マイナスは変数名にはできませんが、後続の「_ー」が数字であれば負の数を表すためのマイナスとなるので、これも問題ない訳です。 ちょっとこの問題の微妙だったところは長音記号のところです。これが実は見た目が同じ「—」(全角ダッシュ)の場合には記号と見なされコンパイルする事ができません。 さて、最後の
は簡単ですね。小文字エックス、アンダーバーの組み合わせはJava識別子として有効なので boolean x_x = true; という変数を定義すれば良い訳です。
水曜日 3 14, 2007
今回はちょっと変り種のクイズです。 顔文字次のプログラムのうち、どのようにメソッドや変数を定義してもエラーとなってしまうのはどのケースでしょうか? switch (face) {
水曜日 3 07, 2007
前回のクイズ シャッフル、ですが、今気づけば肝心の問題の部分が何か、が良くわからない状態になっていました。大変失礼いたしました。もう一度問題をご紹介します。 シャッフル/シャッフル/シャッフルpublic class Shuffle {こ のプログラムは配列の内容をランダムに再配置するというプログラムです。ためしに Integer[] a = {1, 2, 3} という配列をこのプログラムを使って6,000回シャッフルし、その組み合わせの出現数を数えてみると次のようになりました。 [1, 2, 3]=1129, [1, 3, 2]=1029, [2, 1, 3]=1021, [2, 3, 1]=853, [3, 1, 2]=886, [3, 2, 1]=1082} さて、この結果から判断できるのは次の4つのうちどれでしょうか。
水曜日 2 28, 2007
先週はJSPの問題でしたが今回はまたJava SEな感じの問題です。 シャッフル/シャッフル/シャッフル安全なパスワードを作りたい、音楽の再生順序を十分にランダムな順んにしたい、写真のスライドの順番をランダムにしたい、などなど、ランダムに並び替えたい、という事情は実はかなり身近な問題です。今回はそんなプログラムです。なお、今回のプログラムでは、完全にこれが答え!というのはなく、簡単な改造で十分ランダムになるという程度しか回答は用意できていませんがご了承ください。 public class Shuffle {
今週のJavaクイズ(3) 回答編:ある日の為替レート
さて今回の問題はいかがだったでしょうか? すでにJSPで類似のものを実装されていて経験されている方には簡単だったと思います。
ある日の為替レート表示されるレートはそれぞれいくらになるでしょうか? その理由もお考えください。 <%@ page contentType="text/html" pageEncoding="utf-8" %> 回答今回の問題のポイントはformatNumberによって小数点以下がどのように扱われるかでした。まず、これを実行した結果を見てみましょう。
この結果から考えると小数点以下はそれぞれ次のように処理されたように見えます。
どうして同じフォーマットのパターン 0.00 を使っているのにこのように処理が変わってしまうのでしょうか。これは、formatNumberタグが利用しているフォーマッタが、java.text.DecimalFormatで、小数点以下の処理方法がROUND_HALF_EVENだからです。ROUND_HALF_EVENは仕様によると
というように、少数部の左辺の桁が奇数なのか、偶数なのかによってそれぞれ動作が異なるため、今回の問題のように結果が分かれた訳です。
水曜日 2 21, 2007
今回はJSPの問題です。 ある日の為替レート表示されるレートはそれぞれいくらになるでしょうか? その理由もお考えください。 <%@ page contentType="text/html" pageEncoding="utf-8" %>
先週のJavaクイズ(2) 回答編:マルチスレッド環境にて お待たせしました、少し難しめの問題でしたがいかがだったでしょうか?今回の問題は先月の「今月のJava Hot Topicセミナー(1月号)」で山口さんによる「コンカレンシー・ユーティリティのすすめ」をご覧頂くとその問題点と解決策がおわかりいただけると思います。 ではまず問題の復習から。 このプログラムのバグを取り除いてください次のプログラムはupdate(int)メソッドによって今までの最大値と比較して、与えられた数が今までで最大であれば、最大値を更新するようなプログ ラムです。しかし、このプログラムはある状況下で期待通り動作しません。そのバグの内容と、バグを修正したプログラムを考えてください。
public class MaxValue {
回答この問題の解答は幾つかパターンが考えられますが、今回は上記でご紹介したセミナーの資料「コンカレンシー・ユーティリティのすすめ (以下、「資料」と言うときはこの資料のことです)」にそって回答をご紹介します。 このプログラムは一見難の問題も無く動作しそうですが、実はマルチスレッド環境では正しく動作しないことがあります。これはJavaのメモリモデルと深く関わる問題です。 このような場合に、CPU 1でこれから処理を仕様としているときに、CPU 2で今まさに更新されたデータを利用するとするとどうなるでしょうか。このとき、CPU 1はデータが更新された事を知らないので、古い情報を使ってしまう場合があります。 これに対処するにはJ2SE 5.0で厳密に定義されたメモリモデルのルールに従ったプログラミングをする必要があります。 これをふまえてプログラムを修正すると次の2パターンのようになります。 パターン1ではすべてのメソッドを同期化することで安全に呼び出しを行っています。一方、パターン2ではvolatileをmaxを宣言する際に装飾する事で必ずこの変数を読み出す前にキャッシュをクリアし、書き出す時にキャッシュをフラッシュするようにしています。パターン2の方は読み出しについては同期化されないためパフォーマンスのオーバーヘッドが少なくてすみます。 これで十分な場合もほとんどですが、さらにパフォーマンスのボトルネックを減らす方法を考えます。近代的なマルチCPUシステムでは、CPUあるいはそのシステムによってメモリの整合性を保証しつつ値を更新するような命令がサポートされています。その典型的なものがCAS (Compare And Swap)命令です。CAS命令は
のように3つの引数を持つ命令で、v == aなら vに bを代入するという命令です。この操作はCPUあるいはシステムによって整合性が保証されるため、この操作を行うためにロックを取得したり、ロック待ちになるということが無く、(アプリケーションやOSから見て) 処理の流れを止める事がありません。このCAS命令は J2SE 5.0から導入された java.util.concurrent パッケージのユーティリティを使う事で Javaからも利用可能になりました。この concurrentパッケージを使った回答例を見てみましょう。 まずCAS命令を利用するためにjava.util.concurrent.AtomicIntegerクラスを使って最大値 maxを保持しています。そして、updateメソッドでは compareAndSwap (つまり CAS)を使って値を更新しているのです。この compareAndSwapは max == oldの場合には実行が成功して戻り値が trueになりますが、max != oldつまり、別のスレッドによって値が更新された場合には戻り値が falseとなって再度比較を行うようにしています。 このようにしてCPUやマルチプロセッサ/マルチコアシステムで提供されている強力な命令を利用したプログラムに生まれ変わりました。皆さんもこれを参考にしてスループット重視の安全なプログラムを java.util.concurrentパッケージを使って実装してみてください。
水曜日 2 14, 2007
ほんの2〜3年前までは複数のCPUあるいはコアを搭載したコンピュータといえば企業や研究施設以外で目にする事はほとんどありませんでした。しかし、昨今のトレンドではパーソナル向けのコンピュータでも複数コア/複数CPUを搭載する物が珍しくなくなってきました。このような状況になるに従って、今まではほとんど見た事もなかったようなバグが発見される事も珍しくなくなってきました。今回はそんな状況に関する問題です。 このプログラムのバグを取り除いてください 次のプログラムはupdate(int)メソッドによって今までの最大値と比較して、与えられた数が今までで最大であれば、最大値を更新するようなプログラムです。しかし、このプログラムはある状況下で期待通り動作しません。そのバグの内容と、バグを修正したプログラムを考えてください。 public class MaxValue {
先週のJavaクイズ(1) 回答編:何が印刷されるでしょうか?
ではお待ちかねの回答を紹介します。まずは問題とプログラムをおさらいしておきましょう。
何が印刷されるでしょうか?次のプログラムを実行するとなにが印刷されるでしょうか? 答えとその理由をお考えください。 import java.util.*; 回答答えは128です。なぜ?と思われた方も多いかもしれません。まず、一番直感的に答えを考えるならば「何も出力されない」が答えになると推測できます。しかしよく注目してください。ここで、i や mapの中に格納されている変数は java.lang.Short 型であり、 != や == で比較する場合には値ではなく参照を比較していることになります。つまり、この比較は本来は
のように書かなければならなかったのです。ではそれをふまえて考えると、答えは「0」であるという風に判断できます。しかしこれも実は違うのです。ここから先は通常知らなくともあまり差し障りは無いのですが、すこしマニアックな引っかけ問題になっていました。 Java言語仕様第3版 5.1.7 Boxing Conversionによると
このようにJava言語仕様によると、-128から127の間の数字に関しては常に参照も等しいようにすることが決められています。ですから、127を超える最初の数字 128 の参照は等しくならず、印刷されるのは 128 となります。
水曜日 2 07, 2007
Javaエバンジェリストグループでは「2時間で学ぶ今月のJavaホットトピック」と題して毎月無料セミナーを夕方に開催しています。このセミナーでは、だいたい2つ程度のトピックほどのプレゼンテーションの他に、参加いただいた方には大変好評なJavaを使った問題を出題しています。このブログでは過去のセミナーでご紹介した問題を毎週ご紹介していきます。なお、答えは次の週までお楽しみ。 何が印刷されるでしょうか?次のプログラムを実行するとなにが印刷されるでしょうか? 答えとその理由をお考えください。 import java.util.*;
|
|