Java8新機能 デフォルトメソッドと多重継承の違い

以前の記事でデフォルトメソッドについて書いた際、最後に

え、多重継承となにが違うの?
だれかおせーて orz

と書きましたが、やっぱりちょっと違うようです。

ラムダ式のFAQ(http://www.lambdafaq.org/)を見たところ、

Do default methods introduce multiple inheritance to Java?

No, because multiple inheritance is already present in Java. Multiple inheritance of interface types has been a feature of the language since its beginning. Default methods do introduce a new kind of multiple inheritance, namely multiple inheritance of behaviour. Java will still not have multiple inheritance of state, as for example C++ has.

デフォルトメソッドとは、Javaに多重継承を取り入れるということですか?

いいえ。なぜなら、多重継承は既にJavaに存在しているからです。Interfaceの多重継承は、最初から言語の特徴となっています。デフォルトメソッドは、新しい種類の多重継承を取り入れるということです。すなわち、"振る舞い"の多重継承です。Javaは未だに、C++のような"状態"の多重継承を持っていません。

ということらしいです。よく分からないです orz
ここでは

  • Java = "振る舞い"(behaviour)の多重継承
  • C++ = "状態"(state)の多重継承

となっているので、この違いがいったいなんだろうということになります。

ここからはあくまで個人の推測ですが。。。

Interfaceでは出来ないこと

private変数・メソッドの定義

Interfaceでは、privateの変数やメソッドの定義が出来ません。

public interface TestInterface {
    private String value = "test_value";
    private void method1();
    default private void method2() { System.out.println("method2"); }
}

これをコンパイルすると

TestInterface.java:2: エラー: 修飾子privateをここで使用することはできません
        private String value = "test_value";
                       ^
TestInterface.java:3: エラー: 修飾子privateをここで使用することはできません
        private void method1();
                     ^
TestInterface.java:4: エラー: 修飾子privateをここで使用することはできません
        default private void method2() { System.out.println("method2"); }
                             ^

と全部エラーとなります。
ちなみにprivateをpublicにすればコンパイルは通ります。

インスタンス変数の定義

Interfaceで定義できる変数はstaticのしかもfinalのみで、インスタンス変数を定義することが出来ません。
つまり

public interface TestInterface {
    public String value = "test_value";
}

public interface TestInterface {
    public static final String value = "test_value";
}

は同じことになります。
後者のコードをEclipseでチェックをかけると、staticとfinalは不要だから削除するように警告されることもあります。

デフォルトメソッドでは出来ないこと

つまり、デフォルトメソッドでは処理結果の状態を保持することが出来ないということです。
たとえばgetterやsetterを作りたい場合、

public interface TestInterface {
    private String value = "test_value";
    default public String getValue() { return value; }
    default public void setValue(String value) { this.value = value; }
}

と書きたいわけですが、

  • private使えない
  • staticだからインスタンス毎に値を保持できない
  • finalだからsetterで値の書き換えできない

ということで、getter以外はコンパイルエラーとなります。

つまり

「デフォルトメソッドでは状態を保持できないため、そのメソッド内で完結した処理しか書けない」
ということだと思います。
メソッド内で完結した処理を、そのメソッドがどう振る舞うべきかということを(簡単に)記述しているものだと考えたら、

  • Java = "振る舞い"(behaviour)の多重継承
  • C++ = "状態"(state)の多重継承

の違いになるのかなぁと。

次回予告

そもそもラムダ式のFAQなのに、なんでデフォルトメソッドについて書いてあるんだろうと思うかもしれません。

それはデフォルトメソッドがJavaに追加された経緯にラムダ式が関係しているからだと思います。
というか、ラムダ式を実現するためにはデフォルトメソッドが必要だったからなのですが。
FAQを読んで頂ければ書いてありますが、もう昼休みが終わるのでまた次回でw

Java8新機能 ラムダ式で並列処理

一昨日の記事で繰り返し処理をラムダ式で書きましたが、 ラムダ式のいいところは短くなるだけではなく、並列処理が出来るということらしいので朝一でやってみました。

まずは普通に

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
SimpleDateFormat DF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
long start = System.currentTimeMillis();
for (int x : list) {
    try { Thread.sleep(1000); } catch(Exception e){}
    System.out.println(DF.format(new Date()) + ":" + x);
}
long end = System.currentTimeMillis();
System.out.println((end - start) + "ms");
出力結果
2013/05/29 09:28:37:1
2013/05/29 09:28:38:2
2013/05/29 09:28:39:3
2013/05/29 09:28:40:4
2013/05/29 09:28:41:5
5001ms

1つ出力するたびに1秒停止しているので、当然ながら5秒程度かかります。

ラムダ式で

start = System.currentTimeMillis();
list.forEach(x->{
    try { Thread.sleep(1000); } catch(Exception e){}
    System.out.println(DF.format(new Date()) + ":" + x);
});
end = System.currentTimeMillis();
System.out.println((end - start) + "ms");
出力結果
2013/05/29 09:28:42:1
2013/05/29 09:28:43:2
2013/05/29 09:28:44:3
2013/05/29 09:28:45:4
2013/05/29 09:28:46:5
5015ms

あれ、やっぱり5秒。全然並列処理になってない orz

並列処理のラムダ式で

Javadocを見てみたら、ListクラスにparallelStreamというメソッドがあったので使ってみると

System.out.println("---");
start = System.currentTimeMillis();
list.parallelStream().forEach(x->{
    try { Thread.sleep(1000); } catch(Exception e){}
    System.out.println(DF.format(new Date()) + ":" + x);
});
end = System.currentTimeMillis();
System.out.println((end - start) + "ms");
出力結果
2013/05/29 09:28:52:5
2013/05/29 09:28:52:2
2013/05/29 09:28:52:1
2013/05/29 09:28:53:4
2013/05/29 09:28:53:3
2005ms

無事並列処理になりました。
ただ、最初3個が同時に出力された後に残り2個が出力されるので、同時に3つまでしか並列処理されていないようです。この数はCPU数になるっぽいですね。
ちなみにparallelStreamの部分は

list.stream().parallel().forEach(~

でもOKです。

気になったこと

ここで使ってるSimpleDateFormatってスレッドセーフじゃないんですよねw
他にもArrayListとかHashMapとかStringBuilderとか、かなり使用頻度高いクラスも同様なので、並列処理にする時は気をつけましょう。

Java8新機能 デフォルトメソッド

前回に引き続き、Java8の新機能で遊んでみました。

今回はデフォルトメソッドです。
これまではInterfaceを実装したらクラス側で処理を記述する必要がありましたが、Interfaceにデフォルト処理を記述することで、クラス側の記述が不要になります。

まずは確認

public interface TestInterface {
    default public void printTest() {
        System.out.println("Hello Interface!");
    }
}
public class TestClass implements TestInterface {
    public static void main(String[] args) throws Exception {
        TestClass testClass = new TestClass();
        testClass.printTest();
    }
}
>java TestClass
Hello Interface!

2つのInterfaceに同一メソッドの処理が定義されている場合

public interface TestInterface1 {
    default public void printTest() {
        System.out.println("Hello Interface1!");
    }
}
public interface TestInterface2 {
    default public void printTest() {
        System.out.println("Hello Interface2!");
    }
}
public class TestClass implements TestInterface1, TestInterface2 {
    public static void main(String[] args) throws Exception {
        TestClass testClass = new TestClass();
        testClass.printTest();
    }
}
>javac TestClass.java
TestClass.java:1: エラー: クラス TestClassは型TestInterface1とTestInterface2からprintTest()の関連しないデフォルトを継承します
public class TestClass implements TestInterface1, TestInterface2 {
       ^
エラー1個

コンパイルエラーになりました。エラーメッセージが分かり難いですがw
クラス側で処理を実装するとOKでした。

public class TestClass implements TestInterface1, TestInterface2 {
    public static void main(String[] args) throws Exception {
        TestClass testClass = new TestClass();
        testClass.printTest();
    }
    public void printTest() {
        System.out.println("Hello Class!");
    }
}
>javac TestClass.java
>java TestClass
Hello Class!

Interfaceで定義された処理をsuperで呼べるのか

public class TestClass implements TestInterface1, TestInterface2 {
    public static void main(String[] args) throws Exception {
        TestClass testClass = new TestClass();
        testClass.printTest();
    }
    public void printTest() {
        super.printTest();
    }
}
>javac TestClass.java
TestClass.java:7: エラー: シンボルを見つけられません
                super.printTest();
                     ^
  シンボル: メソッド printTest()
エラー1個

だめでした。
Interfaceを1つだけにしてもやっぱりだめでした。

と思ったら、Interface名をsuperの前に指定したらいけるようです。

public class TestClass implements TestInterface1, TestInterface2 {
    public static void main(String[] args) throws Exception {
        TestClass testClass = new TestClass();
        testClass.printTest();
    }
    public void printTest() {
        TestInterface1.super.printTest();
    }
}
>javac TestClass.java
>java TestClass
Hello Interface1!

遊んでみて

え、多重継承となにが違うの?
だれかおせーて orz

Java8新機能 ラムダ式を触ってみました

来年正式版が出るJava8ですが、こちらからDLして昼休みにうわさのラムダ式をちょっと触ってみたので、その殴り書きです。
ちなみにJavadocはこちら

Listの繰り返し

たとえばこんなListがある場合に

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

これまではこんな感じで処理していました。

for (int x : list) {  
    System.out.println(x);  
}

これをJava8で追加されたforEachとか使うと、

list.forEach(new Consumer<Integer>() {
    public void accept(Integer x) {
        System.out.println(x);
    }
});

こう書けます。でもこれはまだラムダ式ではないです。
ここからさらにいろいろと省略することが出来て、最終的には

list.forEach(x->System.out.println(x));

こうなります。

Listの要素をFilter

先ほどのリストから偶数のみを出力したい場合は

list.stream().filter(x->x % 2 == 0).forEach(x->System.out.println(x));

こうです。
最大値を取得する場合は

System.out.println(list.stream().map(x->x).reduce(0, (x, y)->x > y ? x : y));

こう書けますが、最大値取得はよくある処理なので、既にmaxメソッドが用意されており、

System.out.println(list.stream().max( (x, y)->x - y).get());

少し短くなりました。
他にも、Mathクラスを使用して

System.out.println(list.stream().reduce(0, Math::max));

こうも書けます。
今はListの中身がIntegerですが、たとえばPersonクラスのListから最年長の年齢を取得する場合だと

public class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
List<Person> plist = Arrays.asList(
    new Person("Tanaka", 22),
    new Person("Suzuki", 31),
    new Person("Yamada", 27)
);
System.out.println(plist.stream().map(p->p.age).reduce(0, Math::max));

これで31が出力されます。
年齢だけではなく、Personクラスをとりたい場合は、

Person p = plist.stream().max((p1, p2)->p1.age - p2.age).get();
System.out.println(p.name + "(" + p.age + ")");

こんな感じです。

触ってみて

コードが短く書けるのはうれしいですが、慣れるまでは時間掛かりそうだなと。
ベテランが集まってやるなら良いですが、新人がどんどん入ってくる現場でいきなりラムダ式バリバリなコード渡して直せとか言うのも酷な気がw
でも個人的には好きなので流行って欲しいです。

AWS体験ハンズオン ~アカウント開設+仮想サーバーAmazon EC2編~

5/21にAmazon本社で行われた「AWS体験ハンズオン ~アカウント開設+仮想サーバーAmazon EC2編~」に参加してきました。

EC2インスタンス作成して、SSH繋いでApache起動とか、固定IP取得とか、ほとんど前にやったのと同じ内容でしたが、新しいことも学べたのでそのメモです。

AWSクラウドデザインパターン(基本編)

Snapshotパターン

実行中のEC2インスタンスのバックアップを取る。

EBSスナップショット

2回目以降のスナップショットは差分のみ保存される。

Stampパターン

稼働中のEC2インスタンスAMIを作って複製する。
Snapshotから作成することも可能。

No Rebootにチェックを付けると再起動しないで作成できるがお勧めしない。
データ書き込み中とかの場合に整合性が取れなくなる可能性があるため。

Scale Upパターン

CPUやメモリなどのスペックを変更する。

Ondemand Diskパターン

ディスク容量を変更する

2つの方法がある。

  • 新しいディスクを増設
  • 既存ディスクを拡張

新しいディスクを増設

EBSを新たに作成。 アタッチしたいインスタンスと同じAZにする必要がある。

フォーマット
sudu mkfs -t ext4 /dev/sdf

マウント
sudo mkdir /ebs sudo mount /dev/sdf /ebs

既存ディスクを拡張

  1. スナップショットを作成
  2. 容量を増やしてVolumeを作成
  3. 前のディスクをディタッチ
  4. 新しいVolumeをインスタンスにアタッチ
  5. デフォルトでは増量分を認識しないので、コマンドを叩く

その他

1週間以内にアカウントとった人はEC2作成するとデフォルトでVPC内に作成される。

VPCにするとTenancyというオプションがある。
 AWSは同一ハード上に複数ユーザのサーバーがある。
 コンプライアンスで問題ある場合は、Tenancyを有効にすればハードを独占できる。ただし高い。

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

業務システムエンジニアのためのHTML5勉強会#02

2013/5/10に行われた業務システムエンジニアのためのHTML5勉強会#02に参加してきました。
いわゆる"HTML5の最先端を学ぼうぜ!"ではなく、実際の業務に活用できることを学びましょうという会です。

ATENDのページから抜粋

イベントコンセプト

近年、Web技術の急激な発達により、業務システム分野にもHTML5への需要が増しています。しかし、HTML5は組込み系からゲーム系まで様々な分野を巻き込み仕様化が進み、またポテンシャルへ疑問を感じるような仕様も数多く存在します。このイベントは、そんな状況に置かれたHTML5などのモダンなWeb技術を、先進性より安定性を重視する「業務システム」へ活用する方法について、議論・情報共有を行うための勉強会です。

第1回も申し込みましたが諸事情で参加できなかったため、とても楽しみにしていました。

Webアプリ開発プラットフォームを使ってみる ~Wakandaの巻~

原田光一さん (4D Japan 技術部)

Webアプリ開発プラットフォーム Wakandaの紹介

DBだが開発プラットフォームとしても使える
ビジネスにフォーカスしたWebアプリを作るためのプラットフォーム
オープンソースでGITで公開されている。

Wakandaサーバー

含まれるもの

  • HTTPサーバー
  • JS実行エンジン
  • JSフレームワーク
  • NO SQL DBMS

DBアクセス

  • Server JS API
  • REST API
  • Client JS API

検索結果をJSONで取得することができる。 JavaScriptAPIもある。

Wakanda Studio

アプリの開発をサポートしてくれる。
必須ではないが効率が上がる。

標準技術のみで作成される。

  • HTML
  • CSS
  • JavaScript
  • JSON

裏で変なファイルを作ったりはしない。

比較的新しいブラウザしか対応していない。
CSS3をフル活用しているので、IEは9から。

Windows7以降に対応

参加者受付システムの開発デモ

かなりVBライクにアプリ開発が可能。
画面項目とDBの紐付けも簡単に。
JavaScriptの処理書いたらすぐにテスト実行。
プログラミング無しで、リストで選んだら横の詳細欄にその値が出たりも。

websocketでバックエンドプログラムのコンソールメッセージをブラウザに出してみた

竹内佑介さん (株式会社ビーエスピー)

なぜ作ろうと思ったのか

セッション0の分離でコンソールメッセージが見えずらくなる。

Windows2003まではサービスとファーストログオンユーザのユーザセッションが同じだった。
⇒セキュリティ上問題がある。

Windows2008から、サービスとファーストログオンユーザのセッションが分離されたため、Tomcatなんかのログが見ずらくなった。
プロセス間通信とかメッセージ表示アプリとか作ればできるけど大変。

JavaScriptでソケット通信できるって聞いたから、ブラウザ上で見れて便利じゃねと思ったので手を出してみた。
これができれば、いろんなOSやスマホなんかでも見れていいんじゃないか。

サーバーサイドはとりあえず最近よく聞くnode.jsで作ってみた。
シンプルで細かいところまで作れていい。
2,30行程度で、Apacheのような簡易Webサーバーが作れる。
プロセス間通信以外でHTTPリクエストより低い階層でプログラムができる。

構築

バックエンドアプリからnode.jsに値を渡してブラウザへ送る。
バックエンドアプリ⇒node.js間が大変だった。(パイプ通信を使用)
パイプのバッファリング処理で、一定サイズまで値を保存してから出力するため、node.jsで値が拾えなかった。 Websocket通信はたくさんサンプルがあるので、そんなに苦労しなかった。

その他

Websocketは双方向通信なので、逆にバックエンドアプリへコマンドが遅れるんじゃないか。

WebsocketはIE10以上じゃないと使えないので、業務アプリとしては微妙。

ブラウザ開けばすぐにログのtailが見れたら確かに便利かもと思いました。
セキュリティ的な問題もありますが、社内のテスト環境とかで作ったら面白いかもしれません。

グラフ描画JSライブラリ ~サーバ負荷を最小に抑えてグラフを出力する方法~

川田寛さん (html5jえんぷら部 部長と雑用)

なぜグラフ描画?

古典的グラフ描画はサーバーで作成してクライアントへ送信。
これからはデータだけ送信してクライアントで描画にシフト。

フロントエンドのグラフ描画はFlashでもできたけど、AdobeもHTML5へシフトしてる感が否めない。

ライブラリが世の中にわんさかある。
俺が最高のライブラリを選んでやるぜ!
⇒20個くらい試したけど、多すぎて無理ゲー

でも20個試したので紹介します。

jQuery-visualie plugin

IE6も対応
入力がtableタグ

グラフ描画した後もテーブルタグがそのまま残るw

実装はCanval+ulタグ
bootstrapと併用するとulタグが競合してデザインが崩れる。
修正あきらめて次へいった。

Sencha Touch Charts

GPL v3(完全に無料じゃない)
入力はJSON
レスポンシブデザインも対応

グラフ描画のパラメータが多い。300行くらい書いたw
まぁ慣れれば。。。

値がすべてCanvasに含まれるので分析できない。

グラフはゲームとかと違い構成要素がシンプルなので、Canvasにしなくてもいいんじゃないか・・・

HighchartsJS

描画はSVG
jQueryプラグイン型
プロパティのしては100行程度
SVGなので、Chromeでも要素の解析が簡単

JSONで値が指定できるが、CSSに書く必要がある。。。
保守性とかどうよ

選定

  • グラフの機能
    • どんなグラフが使えるか
    • 何次元対応か(見落としがち)
  • 項目が長い時のデザイン補正方法
  • データの入力方法
    • JQueryライク?JSON?
    • データ生成の生産性
  • 描画方法
    • ユーザCSSの影響は?デザイン制限は?
    • プロパティの可視性?デバッグ可能?
  • 環境と性能
    • IExx対応と言っていても実際は?

入門 HTML5

入門 HTML5

HTML5ガイドブック 増補改訂版 (Google Expert Series)

HTML5ガイドブック 増補改訂版 (Google Expert Series)

  • 作者: 羽田野太巳,古籏一浩,太田昌吾,小松健作,伊藤千光,吉川徹
  • 出版社/メーカー: インプレスジャパン
  • 発売日: 2012/10/19
  • メディア: 単行本(ソフトカバー)
  • 購入: 3人 クリック: 6回
  • この商品を含むブログを見る

第38回HTML5とか勉強会「Webアプリ×テスト最新事情」

2012/4/26に行われた第38回HTML5とか勉強会「Webアプリ×テスト最新事情」に参加してきました。
JavaScriptのテストフレームワークについていろいろな話を聞くことができました。

遅れて参加したうえに、ノートパソコンの電源入れたとたんに電池切れ orz
途中の休憩時間にコンセントのある席へ移動したのですが、前半はメモれてないですw

メモとるのが全然追いつけなかったので、コードとか省略してたり間違ってたりすると思いますが、雰囲気だけでも感じて頂ければと。

Sinon.jS

外村和仁さん

テストしにくいもののダミーを作成する。

spy

メソッドの代わりにダミーを作成できる。

// オブジェクト作成。spyはメソッドオブジェクト
// これをテストしたいメソッドを上書きする感じで。
var spy = sinon.spy();

// 試しにメソッド読んでみる
spy('foo', 'bar');
spy('foo');

// 結果をチェック
spy.callCount;   // メソッドが何回呼ばれたか(この場合2)
spy.args[0][1];  // 引数に指定された値を取得(この場合'bar')

stub

spyができることは全部できる。
window.confirmとかを上書きできる。

途中で確認ダイアログがあるような処理だと自動テストできないので、

// 確認ダイアログを上書き
sinon.stub(window, 'confirm');

// ダイアログで"いいえ"が押されたことにする
stub.returns(true);

// 最後に開放しないと上書きされっぱなしに
stub.restore();

mock

spy,stubの機能をすべて持っている
あらかじめメソッドがどう振る舞う決めて実行する

mock.expects('validate')
  .once()
  .withArgs('')
  .returns('hogehoge');

mockで出来ることはstubでもできるので、どちらを使うかは好みの問題。

Fake Timer

曜日チェック処理で

// 日曜日だったらtrue
if (new Date().getDay() === 0) { return true; }

みたいな処理があると、日曜しかテスト成功しないw
そこで、JavaScriptで取得する当日日付を変更できる。
(コードはメモれませんでした orz)

他にもsetTimeoutで10分待つような処理がある場合、テストも10分かかってしまうw
でもこれをつかうと指定した分だけ時間を進められる。
⇒setTimeout や setInterval で使われる時間にだけ有効

Fake XHR

ajax のテストとか。
stubでもがんばればできるかもしれないけと、もっと低レベルのところをダミー化する

var xhr = sinon.useFakeXMLHttpRequest();

リクエストのオブジェクトをチェック
任意のレスポンスやHTTPコードを返す

JSテストフレームワークの比較

佐伯さん(TIS)
@ITでJavaScript入門記事や他にもいくつか連載

QUnit

  • もとはjQuery用のテストフレームワークだったが、今は汎用的になっている。
  • 同期/非同期サポート
  • APIで外部ツールと連携可能
  • Pluginいっぱいある

Mocha

  • Expressの作者が作成
  • 非同期サポート
  • assertion libraryを選択して利用
  • TDD、BDD、Qunit等のスタイルが選択可能
  • レポートの形式が豊富
    • Dot Matrix
    • Spec
    • TAP
    • Landing Strip
    • List
    • Progress
    • nyan(猫が出てくる?)

JsTestDriver

  • Googleが作成
  • Javaが必要

Karma

  • Angular.jsチームが作成
  • TestRunnerなのでJasmine等のフレームワークは選択できる
  • 主要なCIツールとの統合が容易

Capybara-webkit + Cucumber

  • Cucumber
    • ユーザ受け入れテスト向けに作られたツール
    • ユーザ操作をfeatureとして日本語で書ける

どうやってえらぶか

以下を考慮して選択する。

  • 何を作るか
  • 何を使ってつくるか
  • どうやって作るか
    • TDD?BDD?
    • メンバーは?
    • 自動化は?
  • プロダクト事態や開発の持続性・継続性を支える物のいう意識を持つ

でも結局は、書いていて楽しいのでw

講演者による座談会

テスト未経験者に取り入れてもらうには

  • トップダウンで強制
  • ゲーム感覚で、レッド→グリーンになるのが楽しくなってきた。
  • 経験者がテストのスケルトンを生成するスクリプトを作って少しでも簡単に作れるように。
  • いきなり全部じゃなくて、ライブラリとかにだけ作ってみるとか。

テスト書いてよかったエピソード

  • テストがあるとリファクタリングが安心してできる。
  • コードを書くとき、最初の滑り出しがよくなる。
  • 1年前の自分のコードをメンテナンスしたときに俺ナイス的なw

システムの規模は?

  • 今のプロジェクトがJSで17万行で、テストコードが2万行くらいあった。
    去年はもっと少なかった。結合テストもやっている。

カバレッジは?

  • 3割くらいを目指してる

UIのテストどこまでやってるか

  • Seleniumは膨大な量になるので、受け入れ条件を満たすためのものだけ。
    内部の細かいのはUTでカバー
  • Modelのみのテストしか出来ていない

TDD vs BDD

  • 正直あまり変わらないんじゃないか
  • 書き方はBDDの方が好き

AWSはじめました

先日やっとAWSに手を出したのでそのメモ

アカウント作成

↓の資料を見ながら、特に問題なく作成できました。

http://www.slideshare.net/kentamagawa/3aws

普段買い物で使ってるAmazonアカウント使えるのは便利ですねー
登録にはクレジットカードが必要です。

Webサーバ立ち上げ

同じく↓の資料を参考に作業しました。

http://www.slideshare.net/kentamagawa/3amazon-ec2

ただ、資料の画面が古いので適時読み替える必要があります。

  • P5 リージョンの変更は画面右上の"Oregon"をクリックします。

    f:id:yuji0316:20130424090623p:plain

  • P11 Termination Protection
    AWSのインスタンスを止めるにはStopとTerminationがありますが、"Termination Protection"をチェックするとTerminationが出来なくなります。設定は後から変更可能です。
    最初よく分からずにTerminationをして、それまでの作業内容が全て消えてしまったので、チェックすることをお勧めします。

    • Stop:単純に停止。後から再起動可能
    • Termination:インスタンスを完全に破棄

今回AMIは"Amazon Linux AMI"を選択しました。
AMIにもよるかもしれませんが、P27-28でやってるEBSのアタッチやマウントは既に行われてるので不要です。
ルートフォルダ自体がEBSにマウントされてるって感じっぽいですがあってますかね?>だれかw

PoderosaでのSSH接続

上記スライドのP20あたりでTera TermでSSH接続を行ってますが、代わりに普段愛用しているPoderosaで繋ごうとしたところ、

"Wrong key format"

と言われてエラーになりました orz
ただ、↓を参考にputtygenでキーファイルを変換したら繋げました。
http://ryooo321.blogspot.jp/2011/10/amazon-ec2ssl.html

すると今度はログイン後に

"未サポートのエスケープシーケンスを見つけました。 ESC [?1034h"

とか言われてやはりエラーになったのですが、今度は↓を参考に接続時の種類をxtermからktermに変えて無事解決。
http://d.hatena.ne.jp/pg_sugarless/20091217/1261059949

ちなみにTera Termだと何の問題も無く繋げました。

その他

Tomcat インストールしました。

sudo yum -y install tomcat7

ApacheとTomcatが自動起動するように設定しました。

現在の自動設定状態確認  
sudo chkconfig --list

自動起動ON  
sudo chkconfig httpd on
sudo chkconfig tomcat7 on

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン 設計ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

Amazon Web Services クラウドデザインパターン実装ガイド

丸の内MongoDB勉強会 #9 in 楽天

2013/4/17に行われたMongoDB勉強会に参加してきました。

内容としてはいろいろあったのですが、そのうちWorking Set Analyzerについて書きます。

Working Set Analyzerとは

2.4で追加された新機能
メモリ上で保持しているデータ量なんかを見ることができます
データすべてチェックしてるからコストが高い処理なので、頻繁に使うのは避けた方がいいそうです。

使い方

現在のステータスを確認するコマンドとして

db.serverStatus()

がありますが、デフォルトでは表示されないので

db.serverStatus({workingSet:1})

とします。
するといろんな値がどばーっと出てきて見づらいので、対象の値だけを見たいなら

db.serverStatus({workingSet:1}).workingSet

と打ちます。すると

{
    "note" : "thisIsAnEstimate",
    "pagesInMemory" : 114700,
    "computationTimeMicros" : 33046,
    "overSeconds" : 1189
}

と表示されます。
ちなみにWindowsだと

> db.serverStatus({workingSet:1}).workingSet
{ "info" : "not supported" }

と表示されて、どうやらサポートされてないっぽいです。orz (参考)
Windowsはメモリの値とかとるのが大変だからじゃないかという話も。。。。

説明

  • note
    あくまで見積もりの値であって正確ではないですよと

  • pagesInMemory
    一番メインとなる値で、メモリのサイズを表しています
    ただ、PCに実装されているサイズよりも大きい値が出てきたりして、ぶっちゃけバグってますw
    今回講演してくださった楽天の窪田さんのブログに詳しく書いてあります。
    カーネルのソースまで見て解析してますw

  • computationTimeMicros
    取得にかかった時間です。
    データが増えると結構時間かかるので頻繁にたたかない方がいいです。

  • overSeconds
    一番古いのから新しいデータまでの登録時間の差です。
    古いのから消されていくので、使い方が悪い(同じデータばっかり使うとか)場合はこの数字がすごい増えていく。1万とか。
    ずっと使っていてこの値が減ってきたらメモリ足りないかも。本家では15分切るとやばいと書いてあったそうです。5分切ると性能的にやばいかも。
    この値は正しいので、いまはこの数字を信用するw

その他

ソートしてる時のデータロック時間とかわかるコマンド
ノートPCで1000件をソートしたら10ms秒位かかってました。

db.setProfilingLevel(2)
show collections (system.profileが増えてます)
db.system.profile.find()

MongoDBのはじめての運用テキスト

MongoDBのはじめての運用テキスト

MongoDB: The Definitive Guide

MongoDB: The Definitive Guide

AngularJSの勉強会に参加してきました。

2013/4/4に行われたng-mtg#2 AngularJS 勉強会に参加してきました。

少し遅れたので最初の方は聞き逃してしまいましたが、私のような初心者向けの内容で、とても楽く勉強になりました。

セッション1

講演者

金井 健一さん

フリーランスでAngularJSコミュ管理人

ドキュメント英語しかなく現在翻訳中なので、仲間を絶賛募集中!

AngularJSについて

最新は1.0.5

コンセプト

その他いくつかありましたが、PC立ち上げたりしててメモ取れませんでしたw

得意なこと

  • CRUD系アプリ
  • 管理画面・マイページ
  • 1ページで完結するアプリ

苦手なこと

  • モバイル向け
  • ゲーム等のグラフィック系、エフェクト系
    • BombermineというAngularJSを使って作られたゲームがある
      • 1000人同時対戦のボンバーマン
      • 向いてないって言ってたのに作っちゃった
      • ソース見てみたけど結局あまり使ってない
      • ステータス持ってたりとか、簡単なポップアップで使ってたりとか

コーディング

テキストボックスに入力した値を別エリアに出すとかならJS書かなくてもできる。JQueryではちょっと書く必要ある。

例えば

<div ng-app>
<input type="text" ng-model="name"><br>
値は {{ name }} です。<br>
</div>

とか。
動作確認はこちらで出来ます。

ng-xxxって属性の書き方はHTML5のバリデーションでエラーになる。
でもdata-ng-xxxって書けばOK。
x-ng-xxxとか他にも書き方あるけどなぜxかは不明。

Hello {{ firstName + lastName}}<br>

とかHTMLに計算式もかけちゃう。

フォーマット変換も簡単にできる。
金額とかは

値は {{ val | currency }} です。<br>

って書けば

値は $130.25 です。

みたいな。
デフォルトUSドル表示だけど、円表示にすることも可能。 ただ、円でも.00ついちゃうバグがあって、現在issueとして上がっている。

繰り返しも楽で、ソートなんかもHTMLだけでいろいろチェインできる。

{{ list | orderBY:'name' | limitTo:2 }}

listは配列とかJSONとかのリスト

バリデーションはng-pattern属性つかって、正規表現もOK

ng-pattern="/^ang-/"

とか。正規表現の時は"/"忘れずに!

ディレクティブ
独自でタグや属性やクラスも作れる。
ng-じゃなくてもOK。
コメントもコンポーネント化できる。←未確認
うまくできればコメントだけで作られたサイトも作れる

セッション2 「AngularJSで開発したい」

講演者

吉田 徹生さん

先月までNHNJapanで今月からLINE株式会社
Naverまとめとか

所属

  • AngularJS Japan User Group
  • WEB技術先端味見部

AngularJSについて

最新は1.0.5.
3,4ヶ月に1回くらいバージョン上げてる。

公式ダウンロードからExtraリンク押すと公式モジュールをいろいろダウンロードできる。
ng-cookieとかはこっちに入ってる。

公式サイトのリンクからJSFiddle飛んでもエラーで動かないのとかあるw

引数名をStringにしてチェックしてるので違うとエラーになる。順番は関係ない。

開発ツール

AngularJS Batarang (Chrome拡張機能)

スコープ内プロパティ見れる

パフォーマンスが確認できる

依存関係がいグラフで見れる

超使える!っていうか無いと無理。開発速度が全然違う!

Karma(元Testacular)

TestacularからKarmaに名前変更
AngularJS専用から他のJSでも使えるようになったはず。(未確認)

Node.jsを利用

各種ブラウザでテストできる

Jasmine等のテストライブラリーがつかえる

ターミナル・ブラウザ間でリアルタイムでテストできる

ファイル更新で自動テスト

感想

なんといっても、簡単なことであればJavaScript書かずにHTMLだけで済むのがすばらしい!
欠点としてはファイルサイズがちょっと大きいこと。

お客さん向けのプロトタイプならJQueryより全然楽かと。
今まではちょっとした見た目の動きの変更でも裏ではガリガリ書いたりとかあったけど、そういった外見と内部の複雑度合が結構比例するような気がします。

JSFiddleって知ってはいたけど、今回初めてつかってみたら超便利!
聞きながら同時に書いてすぐ動作確認してAngularJSスゲーとか。

ng-appで適用範囲とか限定できるので、うまく作ればHTMLからJavaScriptの対応するコード探したりとかが楽になりそう。

あと、便利なモジュール作って配布したりすれば面白いかなぁと。

次回は6月頃を予定しているそうです。 AngularJSが1.00になってから1周年なので何かしたいなぁとか話してました。