C++のstd::abs()で絶対値をとる時は注意が必要だった

CodeIQでひさしぶりにC++を書きました。
そのとき、ある整数の絶対値をとりたくてstd::abs()を使おうと思ったのですが、
コンパイルエラーになったりしたので調べてみたら、単純そうで罠のある関数だったのでメモです。

整数の絶対値は取得できない?

下記のコードの結果は?

#include <cmath>
#include <iostream>

int main() {
	std::cout << std::abs(-1) << std::endl;
}

C++03の場合

cmathの中のstd::abs()は、整数を引数に取れないそうです。
すなわち、上記のコードはコンパイルエラー。
(cstdlibの中のstd::abs()は整数を引数にとれるっぽい)

C++11以降の場合

int型を引数にとるstd::abs()がcmathに定義されているので、上記のコードは1と表示する。

これから先の仕様変更?

std::abs(u0)のように、unsignedな整数を引数にしたときにどの関数を呼び出すか解決できない問題があり、この先の仕様がどうなるか不明という話。
そもそも符号なし整数の絶対値を計算する必要は無いと思うのだが…
https://wg21.cmeerw.net/lwg/issue2192

コンパイラの実装が問題をややこしくする

問題の無い実装

先ほどと凄く似ていますが、下記コードの挙動は?

#include <cmath>
#include <iostream>

int main() {
	std::cout << std::abs(-2.3) << std::endl;
}

このコードは、

  • GCC 7.1(C++1z)
  • Clang 4.0.0(C++1z)
  • MSVC 14.1 = Visual Studio 2017

のいずれでも同じで、期待通り”2.3″と表示してくれました。

stdと書き忘れた時の挙動

ただ、1回まちがえて、下記のように記述してしまいました。

#include <cmath>
#include <iostream>

int main() {
	std::cout << abs(-2.3) << std::endl;
}

こちらの挙動はどうでしょう?

実は、上記3つのコンパイラのうち、GCCだけが
“2”
と表示します。(ClangとMSVCは”2.3″と表示します)

includeを忘れたときの挙動

それから、さらに

#include <cmath>

を書き忘れたときの挙動も違います。

  • GCC : cmathを書いた時と同じ(std名前空間指定ありなら小数、なしなら整数で返す)
  • Clang : コンパイルエラー
  • MSVC : cmathを書いた時と同じ(std名前空間の指定有無によらず小数で返す)

どうやら、
GCCにおいて#include <cmath>したときは、std名前空間内にしか関数定義を展開しない、
GCCとMSVCでは#include <iostream>しただけで<cstdlib>,<stdlib.h>相当の関数定義が展開される
ということが起きているみたいです。

感想

std::abs()という極めて単純な関数でも、仕様のバージョンによる違いやコンパイラ依存が多くあることを学びました。
C++のコンパイラについて、LinuxならGCCかClang、WindowsならMSVCが向いていると思っているのですが、全部に対応するライブラリを作るというのは思った以上に大変そうです。

今回はCodeIQでコンパイルエラーが出て気付きました。
手元では正しく動くのに、CodeIQなりPaizaなりオンラインのプログラミングコンテストなりのサイト上では挙動が違う なんてこともあり得るのかと思うとちょっと怖いですね。

参考/利用サイト

cpprefjp C++ 日本語リファレンス

wandbox.org : GCCとClangの挙動確認に使いました

広告

メルセンヌ・ツイスターについて(4年経ってからの追記)

背景

疑似乱数生成のアルゴリズムに、メルセンヌ・ツイスター法というのがあります。
C++11ではこれが使えるということで、2013年にブログに書いたんですね。

記憶によると、Google日本語入力を入れたら顔文字がたくさん候補に出てきて楽しかったからたくさん使っていたあれな投稿になっています(・ω・) ←こんな感じ

そんな記事ですが、なぜか毎月100近いアクセスがあります。
多くは検索エンジンのクロールなんでしょうが、このブログ内でトップアクセス数を維持している以上、見てくれている人もいるのかなと。

だったら多少は情報を追記しようというのが投稿理由です。

動向

少なくとも自分の聞く限りでは、最近の言語でメルセンヌ・ツイスター以外のアルゴリズムが積極的に取り入れられたという話は聞きません。(※その道の専門家とかではありません)
また、Mersenne Twister Home Page (開発者のページ)も、2013年の記述が最後になっているように見えます

が、リンクの張られているメルセンヌ・ツイスター関連ライブラリや改良アルゴリズムはそこそこの頻度で更新がされているようです。
特に、高速版である SIMD-oriented Fast Mersenne Twister (SFMT)  は、このブログ執筆時点(2017年7月)での最新版が2017年2月となっています。バグフィックスのようです。

オリジナルのメルセンヌ・ツイスター、SFMTともにBSD系ライセンスのため、他の多数のライブラリに直接的/間接的に組み込まれているはずです。
もしかしたら、いくつかの言語の実装に影響があるかもしれませんね。

あくまで疑似乱数:暗号化には使ってはいけない

真の乱数なるものをコンピューターで生成できるのかどうかは私には分かりませんが、
メルセンヌ・ツイスターが真の乱数ではなく疑似乱数なのは間違いないので気をつける必要があります。

とは言いつつも、周期長いならセキュリティー的に強かったりしないのかな~とか期待を持ちたくもなります。
でも、絶対にセキュリティーの用途で使ってはいけません。

下記のブログ記事がとても参考になります。
順ちゃん寝る より

メルセンヌ・ツイスター倒されちゃってます…以外と簡単そうに

某人気ゲームソフトの内部でもメルセンヌ・ツイスターが使われていて、
簡単に解析がされてしまったとか。

注意が必要ですね。

感想/その他

この記事の閲覧数もそこそこ増えたりしたら、本当に疑似乱数の記事に需要があるということなので、
論文読むとかしてちゃんとした知識付けたいと思います。

若干話が飛びますが、C言語とかの線形合同法のrand()関数ははやく非推奨になったほうが良いと思う。

Azure FunctionsとLINEとTwitterのAPIを使ってみた

Azure Functionsを使ってみました。
もう少し詳しく書くと、次の通りです。

  • HTTPトリガー, タイマートリガー を試した
  • Azure Table Storageとのバインディングを試した
  • (直接的にFunctionsは関係ないけど) LINE @, Twitter APIをそれぞれ使ってみた
  • 安く抑えた

ソースコードはこちら https://github.com/wkwkhautbois/TweetChecker

何を作ったか

Twitterでのつぶやきを監視して、つぶやきがあったらLINE@でPush通知する仕組みを作りました。
具体的に書くと、アクタス管楽器専門店さんのつぶやきから、自分の使っているリード(=消耗品)の入荷情報だけを拾ってきて、専用のLINE@アカウントに内容をそのまま通知するものです。
「【入荷情報】」というタグや商品名をはっきりツイートしてくれるので、Twitterでの検索は複雑なことをしなくて楽ちん
(著作権どうなのとかあるので個人で利用、そのうち止めると思う。)

※そもそも

自分でプログラムを作らなくても、IFTTTとか使えばできます。たとえばこちらの方とか。
今回はAzure FunctionsやLINE@/Twitter APIを使ってみたいというのが目的の一つ。
あとは、前回書いたように外から見える成果も作っていかないとなと。いや、有用なサービスを作れよという話もあるけれど、題材を見つけるセンスが足りなかったので。

あとは、うかうかしていたらAzure Functions関連で比較的似たようなことやってる記事も出てきたり。
ただ、上の記事ではVisual Studio 2017からのデプロイのようですが、自分はブラウザ(Azure Portal)からなのでちょっとだけ違うといえば違ったり。

構成

TweetChecker_architecture

アプリケーション

Functionが2つ

  • MentionRecieve : LINE@への友達登録などを受け取る関数
  • TweetCheck : 定期的にTwitter検索を行い、新しいツイートが見つかればLINE@にPushする関数

Visual Studio 2017 Tools for Azure Functionsを使うと.csが作られて、コンパイルされたものがデプロイされるみたいですが、
Azure Portal上で編集したので、どちらも Run.csx (.csではない)がテキスト形式でそのままデプロイされている状態になりました。

(試してないのですが、Visual Studio 2015 Tools のほうは.csxがアップロードされるみたいですね。)

ストレージ

本当はRDB(Azure SQL Databaseとか)もしくはJsonをそのまま格納しやすいDocument形式のDB(Azure DocumentDB)を使いたかったのですが、
今回はケチケチ生活でAzure Table Storageのみを利用。

だいぶ使い方を間違っている感があるけど、趣味において安いは正義ですからね(・_・)
DocumentDBもストレージ単価は安そうだったけど、最低でも400要求ユニット(スループット)を契約する必要があり、結果として3000円/月 以上掛かってしまうことに。

試してみたかったことと感想

入出力のバインド

MentionRevieve側では、Azure Table Storageへの読み書きにAzure Functionsのバインド機能を使っています。(比較も兼ねて、TweetCheckではバインドを使わず普通の書き方にしています。)

public static async Task Run(HttpRequestMessage req,
    IQueryable<TableEntity> inputUserTable,
    IAsyncCollector<TableEntity> outputUserTable,
    TraceWriter log)
{
    // 処理
}

Azure Portalの画面から、inputUserTableとoutputUserTableの2つの変数について、それぞれTable Storage内のテーブルと紐付けています。

良いところ

次のように、通常のコレクションのように扱えるのは楽だと感じました。Selectしてくる時は特に。

ただ、大きなプログラムではDBアクセスなどの処理は自作のメソッドでラップしたりすると思うので、Functionsでサクッと書きたい時にだけありがたみのある機能という気がします。

bool hasSameUserId = inputUserTable.Where(x => x.PartitionKey == "User")
                                   .Where(x => x.RowKey == userId)
                                   .FirstOrDefault()
                                   != null;
await outputUserTable.AddAsync(new TableEntity {
    PartitionKey = "User",
    RowKey = userId,
});

辛いところ

バインドに使うクラスの情報が少ないのが辛いです。

例えば、ドキュメント Azure Functions における Storage テーブルのバインド には下記のように記載されています

Node.js または C# 関数でオブジェクトをシリアル化できます。 C# 関数の場合は、次の型にもバインドできます。

  • ITableEntity を実装するすべての型
  • ICollector (複数のエンティティを出力する場合。 サンプルを参照してください)
  • IAsyncCollector (ICollector の非同期バージョン)
  • CloudTable (Azure Storage SDK を使用する場合。 サンプルを参照してください)

ブラウザ上で編集している時にIntellisenseが使えないは当然でしょう。(むしろシンタックスハイライトが付くだけでもありがたい。)
ただクラスの使い方が分からないと話にならないので、クラス名で検索します。
「IAsyncCollector」のメソッド一覧が無いかとWebで検索するわけですが…見つからない。
MSDNとかMicrosoftDocsとかが引っかからない。

便利なライブラリでも、ドキュメントが揃ってないと使われないということが分かった気がします。

安定性

1年以上前のプレビュー版時代の情報ですが、下記の記述が気になっていたので、実際どうなのだろうと。

Azure Functions – C# を活用するために気をつけていることをまとめてみる

Azure Functions は、SLA 100% のような必ず実行される というものではありません。実際、グラニでは128MB では50回の実行で 5回程度は失敗を計測しています。

感想

Functionsの従量課金プランを使っています。
ちゃんと計測している訳ではありませんが、HTTPトリガーもタイマートリガーも順調に動いていると感じます。
(1割も処理が書けていたら動作確認をしているときも気になると思いますが、今回はそんなことはありませんでした。)

ただ、インスタンスの立ち上がり時間(+.csxのコンパイル時間?)として結構とられています。
タイマー起動は、1分程度の遅延を良しと出来るかどうかは気にしたほうが良さそうです。
あるいは、AppServicePlan(有料)と紐付けると常時起動もできるようですが。

その他 気付いたこと

HTTPトリガーのセキュリティ設定が簡単だけど制限がある

APIキー

WebAPIとしてFunctionを用意したときに、誰でも自由にアクセスしてほしい時ばかりではありません。
そんなとき、APIキーのチェックをさせることができます。

  • URLに code=*** の形でキーを指定させる
  • HTTPヘッダに x-functions-key という指定をさせる

の2通りで判定できるようです。今回は前者を試しました。
(URLに見えるのは微妙ですが..)

APIキーが間違っているときは、Functionに到達しないのでログに現れません。当然か..
エラーログが残らないとなると、総当たりで攻撃されて気付いたら破られてたみたいな事にならないんでしょうか…?(今回自分の作ったFunctionでは、さらにLINE APIの認証もあるので大丈夫だと思いますが。)

IPアドレス制限

IPアドレスを絞るという対策もあります。そして先人は既に試しています。Azure Functions に IPアドレス制限をかける / BEACHSIDE BLOG
このときの制限が「従量課金ではないこと」です…これは諦めろということか…
IPを絞ったりしたい場合は、FunctionsのHTTPトリガーを使わずWebAppsの無料プランを使った方が良いかもしれません。

Log出力や管理が楽なような面倒なような

関数を作ると最初から TraceWriterクラスの変数がRunメソッドの引数に設定されています。
こちらを使えばログが出力されるわけですが、
勝手に保存され勝手に消えていくので、長期的に保存する用途には向きません。

log4netとか経由で出力してStorageに保存するのが良いのでしょうが、
Web.configが(従量課金では常に/AppServicePlanでもデフォルトでは)使えないため、
設定が分散したりして面倒になりやすい気がします。

まとめ

  • Azure Functionsを使ってみた。題材として、Twitterの特定のつぶやきをLINE@に転送するアプリを作った。
  • IOのバインド機能は、短めのFunctionで使う分には少し便利。でも情報が少なすぎるのが辛いし無くてもたいして困らない程度のもの。
  • 試した範囲内ではFunctionsは十分安定していた。
  • APIキーの設定は簡単だけど、IPアドレス制限とかは面倒。(ほぼ)無料枠で行うのは無理。
  • Log管理とかも含めて、全体に小さなプログラムで少し使う程度がよさそう。WebAppsはVMの代わりになるかなと思ったけど、Functionsだけでは辛いと思う。
  • 数円/月 の費用で収まりそう(Azure部分)

今後の課題

  • Visual Studio 2017 Tools for Azure Functions を使ってみる
  • 他のバインドも試してみる
  • 車輪の再発明ではないネタを考える

予選落ち(転職ドラフト)

なんとなくだらだらと書きます

事の経緯

転職したい…かどうかは置いておくとしても、
自分の市場価値が知れるのは面白いよねー という話を友達とした。

なるほど確かに。
今の給料にそこまで満足していない(不満というほどでもない)が、
では幾らくらいもらうのが適正なのか?
どこかの広告みたいですが、気になるところ。

そんなわけで転職ドラフトに申し込んだ

転職サイトに登録してみたものの、
日々くるメールの多さにちょっと圧倒された。
(数週間経ったら一気に減ったけど。。)

そんな時にちょうど、転職ドラフトなるイベントが開催されるのを知った。
開催まで数日、準備はまぁ間に合うかなくらいに思えた。

やっぱり真面目に書かないと自分の市場価値は見えてこない。
だから、けっこう真面目に今までの経験を書いた。

タイトルの通りで

予選落ちした。
すなわち、転職ドラフトの事前審査を通過できず。
ちょっと残念。

後から知ったのだけど、最初は落ちましたみたいなブログ記事がWebにはちらほら。
なるほど、予想よりしっかりしたドラフトのようだ。

レジュメを書く中で気付いたこと

自分の経験や考え(レジュメ)を書く中で気付いたことがある。
アウトプットできる情報がしょぼい。

自分の場合、業務の都合上、一つのシステムの企画から運用保守まで携わるということは無い。
そうすると、職務経歴書を書こうと思っても、数ヶ月ごとの細切れの履歴になってしまう。
事実は事実だからしょうが無いのだが、
外から見ると、「大した経験していないな」「一通りの業務をこなせるかどうかも怪しいぞ」と思われてしまう。というか、自分自身がそう思ってしまった。

趣味でコードを書かないわけではない。最近、ちょっとTwitter,LINE@のAPIを使ったものを作ったりしている。
ただ、それも大規模なものではないから、職務経歴書としての見栄えはあまり良くならなかった。(これは自分の書き方の問題もありそうだが…)

ただ、個人開発のものは中身を全て書けるのは良いと感じた。
SIerで働くと、お客様の内部のシステムを作ることが多く、
社名も含めてかなりの部分を隠して履歴を書かなくてはならない。
GitHubにコード上げたので見てください くらい書けるのは、(直接的には人事の心に刺さらない気はするが)判断してもらう材料には十分なる。

自分の能力/市場価値を判断するためには、判断材料を外に出す必要がある。
当然ではあるか。

そんな訳で、自分の頭の中でぼんやり思ったことをアウトプットしてみた。

Javaのenumとswitchとコンパイル結果

はてなブログから戻ってきました。これは過去記事のコピーです。

目的

Oracleの配布しているJDKと、Eclipseで使われるJDKで、コンパイル後のファイル数が違うケースに気づいたのでメモ。
switch文でenumを使う時のコンパイル結果についてです。

本題

Javaのenumが、ただの定数ではなくて特殊なクラスとして扱われるのは有名なことかと思います。EffectiveJava(読みかけ 汗)にも書いてありました。
クラスなので、コンパイルすればenum定義は一つの.classファイルになります。クラス内で定義したら、staticな内部クラスとして、やっぱり別の.classになります。

ところで、そんなenumの利点として、switch文の条件にできるという点があります。
では、このようなコードはコンパイルするとどういったファイル名になるでしょうか?

Person.java

public class Person {
    public void work(Day day) {
        switch (day) {
        case SAT:
            System.out.println("寝て過ごす");
            break;

        case SUN:
           System.out.println("遊びに出かける");
            break;

        default:
            System.out.println("働く");
            break;
        }
    }
}

Day.java

public enum Day {
    MON, TUE, WED, THU, FRI, SAT, SUN
}

Eclipseのコンパイル結果は予想通り

自分は、当然Person.classとDay.classの2つになると思ってました。
そして、Eclipseを使うとその通りになります。(バージョンは4.2と4.5で確認)

Oracle JDKでは違った

でも、OracleのJDK(1.7)のjavacを使ったら、
* Day.class
* Person.class
* Person$1.class
の3つになりました。なぜだ(・д・)

javap Person$1.class とすると、

Compiled from "Person.java"
class Person$1 {
    static final int[] $SwitchMap$Day;
    static {};
}

だそうな???

検索すると次のような記事に当たります

enumの値が変わったり増減したりしても、enumを使う側はコンパイルし直さなくても済むというのがenumの特徴です。そういった挙動を既存の文法だけで再表現するための実装として、Oracleのjavacでは内部的に勝手にクラスを作っていたんですね。そしてEclipseのコンパイラでは別の実装になっていると。

感想

Javaではクラスごとに.classファイルが作られることになっています。
しかも無名のクラスは$1のような通し番号のついたクラスになったりします。

実装依存なのだとしても、コンパイル後のファイル数まで違ってしまうのはなんとも気持ち悪いというか。
たとえば1つの.javaファイルから100個の.classが作られることも許されているのかなみたいな。
コンパイル後のことなんて気にするなと言われれば、まぁそうなんですが…(‘_’)ナンダカナー

ブログ引っ越し(仮)

先々週に、はてなブログに登録しました。
むこうの方が技術ブログ系は揃ってるので、流れに乗れるかな~なんて。
 ひとまず3本書いてみました。
VS2015ならconstexprでコンパイル時演算でき…ない??
うーん、はてブだからってそう簡単にアクセス数が増える訳ではないですね(・ω・;)
こちらの方が一定アクセス常にある感じ。
メルセンヌツイスターを扱った記事だけ妙にアクセスがあったりと、どういった記事に需要があるのかいまいち分からない。
今後どちらをメインにするか、あるいは平行して書いていくか、まだこれから検討します(._.)
——– 2017年5月7日 追記ここから ——–
はてなブログよりwordpress.comのほうが、
アクセス数が多いみたいです。
有効なアクセスの割合がどうなのかは分かりませんが、
こっちに戻ってきてみました。
——– 2017年5月7日 追記ここまで ——–

JSONとAjaxの勉強

さいきんJavaScriptを触る機会がありました。
使うとなったときには急いでパーフェクトJavaScriptを買いに行きました(・ω・)いやー良いシリーズですね

それまではわりと、Ajaxの非同期通信というと難しい,凝ったアプリ作りたい時に使うもの くらいの認識だったんですが、
意外と手軽に身近に使えるものなのだなと。
あと、その時は使わなかったんですが、
AjaxではJSONでデータのやりとりをすることが多いのですね。

勉強したことを復習がてらメモめも(._.)φ

まずはサーバー側。JavaのServletで。
とりあえずこんな感じでJSONファイルをレスポンスとして返す。ちょっとぱっと見ではわかりにくいですね。
話はそれますが、最近はweb.xml書かなくてもアノテーションでURLマッピング書けるということで、こういう時便利ですね(・ω・)

// importとか省略

@WebServlet("/Json1")
public class Json1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("{"
                + "  \"vegetable\" : [\"tomato\", \"carrot\"], "
                + "  \"fruit\" :  [\"orange\", \"apple\", \"strawberry\"]"
                + "}");
    }
// doPostは省略

}

そしてサーバーにリクエスト投げるhtmlがこれ

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
  function createList() {
    var xmlhr = new XMLHttpRequest();
    xmlhr.open('GET', 'http://localhost:8080/WKWKWeb/Json1', false);  // まずは同期通信
    xmlhr.send(null);

    if (xmlhr.status == 200) {
      var data = JSON.parse(xmlhr.responseText);
      var lists = document.getElementById("lists");

      // ループでJSONファイルからの各要素をリストに追加
      for (group in data) {
          // level1
          var dt = document.createElement("dt");
          dt.textContent = group;

          // level2
          for (i = 0; i < data[group].length; i++) {
              var dd = document.createElement("dd");
              dd.textContent = data[group][i];
              dt.appendChild(dd);
          }
          lists.appendChild(dt);
      }
    }
  }
</script>
</head>
<body>
  <input type="button" value="リストを取得" onClick="createList()" />
  // ここに要素が足される

<dl id="lists"></dl>


</body>
</html>

これだけで、ボタンを押すとAjaxでJSONデータを取ってきてリストに追加できる。
ゴチャゴチャしてるけど、ほとんどは読み取ったデータをリストに詰め替える作業で、Ajax自体は簡単じゃないですか~(・д・)

====

さすがにこれでは使いにくいので、ちょっと改良する。
(Ajaxなのに同期通信だし…)

あと、気分も含めJSPつかってみる。直接JSP呼ぶのって常に悪手なのかな。

<%@ page language="java" contentType="application/json; charset=UTF-8" %>
{
    "vegetable" : ["tomato", "carrot"],
    "fruit" :  ["orange", "apple", "strawberry"]
}

クライアントはJavaScriptの部分だけ

function createList() {

  var xmlhr = new XMLHttpRequest();
  xmlhr.onreadystatechange = function() {  // 非同期通信!
    if (xmlhr.readyState == 4) {
      if (xmlhr.status == 200) {
        var data = JSON.parse(xmlhr.responseText);
        var lists = document.getElementById("lists");

        for (group in data) {
          // level1
          var dt = document.createElement("dt");
          dt.textContent = group;

          // level2
          for (i = 0; i < data[group].length; i++) {
            var dd = document.createElement("dd");
            dd.textContent = data[group][i];
            dt.appendChild(dd);
          }
          lists.appendChild(dt);
        }
      }
    }
  };

  xmlhr.open('GET', '/WKWKWeb/Json2.jsp');  // 記述の順番が逆になってしまうのは平行処理の宿命か
  xmlhr.send(null);
}

非同期処理できましたね!確認してないけどきっと出来てるよね!
JSPってHTMLに毛が生えた感じ程度の認識だったけど、
こうやって使うと、あぁサーバー側の処理なんだなぁと実感しますね。

====

実際にはJSPに固定でJSONデータなんて打ち込むことは無いだろうし、
クライアントもjQueryくらい使うでしょう。
ってことで第3のバリエーション。

// ライブラリ使いました
import net.arnx.jsonic.JSON;

@WebServlet("/Json3")
public class Json3 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // JSONに変換されるクラス
    // privateフィールドとpublicアクセサの組でも良いらしい
    public class Foods {
        public String[] vegetable;
        public String[] fruit;
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json;charset=UTF-8");

        // JSONデータの生成
        Foods foods = new Foods();
        foods.vegetable = new String[]{ "tomato", "carrot" };
        foods.fruit = new String[]{ "orange", "apple", "strawberry" };
        String json = JSON.encode(foods);

        // クライアントに返却
        PrintWriter out = response.getWriter();
        out.print(json);
    }
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>

  function createList() {
    $.ajax('/WKWKWeb/Json3', {
      type : 'GET',
      dataType : 'json',
      success : function(data, status, xmlhr) {

        for (group in data) {
          // level1
          var dt = $('<dt></dt>')
                .text(group);

          // level2
          $.each(data[group],
            function(idx, elem) {
              $('<dd></dd>')
                .text(elem)
                .appendTo(dt);
            }
          );

          dt.appendTo('#lists');
        }
      }
    })
  }
</script>

世間では常識となった(らしい)jQueryと、
どの程度有名なのか分からないけどJSONICというJavaのインスタンスとJSON形式文字列の相互変換ライブラリを使ってみました。
実際に何か作る時には最低限このくらいはしたいなー。
jQueryの作法とか知らないのでもっと便利な書き方はあるのかもしれないし、
JSONICの方もpublicなフィールドを直接使ってしまってJavaっぽくない書き方してしまいましたが、
とりあえず便利ですね(・ω・)

世間の人からしたら常識なのかもしれないけど、
Webではなく画像処理とかCGとかやってた人間からすると、
知らないことが多いですね。