XP祭2011でセッションを開催しました

セッションにお越しいただいた皆様ありがとうございました。
以前からレガシーな開発スタイルからアジャイルな開発スタイルへどのように移行させるかという漠然とした悩みというか課題を持っていました。アジャイルな現場とレガシーな現場でどのようなことが起こっているのかを対比してそこから何か見えないだろうかという思いがあって今回のセッションを企画しました。
その中で、アジャイルサイドを語るうえで先進的な取り組みをしている方に是非登壇して頂きたいと思い、飲みながら@kwappaさんに「こんなんやりたいんですよね〜」とお願いした所、「いいよ。やろうよ。」と軽く引き受けてくれたので今回のセッションを開催される流れとなりました。

僕が話をしたレガシーサイドのスライドです。正直な所、現在も将来も明るい世界ではありません。セッションに参加された方が現場で宗教戦争を起こして少しでも何か変わればそれはとっても嬉しいなって・・・

今回のセッションは残念ながら録画や中継がありませんでした。どこかで同じような悩みを持つ人たちにもこの内容を届けたいと考えています。どこかの勉強会やイベントでこういう内容でセッションが出来る場を提供していただけるのであれば喜んでうかがいますのでregtan1210_at_gmail.comご連絡頂ければ幸いです。

最後になりましたが、お忙しい中無茶なおねがいを引き受けてくださった@kwappaさん、こちらも無茶ぶりで会場に来て頂いた看板娘の@shokosさん、アジャイルなポーズの素敵な写真や貴重な事例を惜しみなく提供して頂いた株式会社ドワンゴ様、セッションの運営にご協力頂いたXP祭のstaffの皆様、本当にありがとうございました。

FizzBuzzを入社試験に出したらどこを見るか

宗教戦争の恐れが多分にあるけど僕だったらどのあたりを注目するかというのを書いてみようとおもいます。基本的にはJavaでの実装の話です。
ソースはregtan/fizzbuzz - GitHub

ターゲットとしてる人物像などなど

中途採用や派遣業者からの紹介でJavaの経験があると言われている人を対象にしていて、プロジェクト内での実装を担当してもらえるような人物を求めています。回答の形式としては、その場で出題しエディタあるいはIDEを使って書いてもらう感じです。

FizzBuzzについて

if文とfor文と除算処理さえわかればできる処理なので基本に忠実に書けば問題なく実装できる処理です。処理の仕様としては、1〜100までの数字を順に、3の倍数の時はFizz、5の倍数の時はBuzz、3の倍数かつ5の倍数の時はFizzBuzz、それ以外の場合はその数字を標準出力に表示するという感じです。詳しくはおググりになってください。

ダメな例

まずダメな例はループカウンタ+1を評価したり、出力しているものです。
https://github.com/regtan/fizzbuzz/blob/master/src/org/kirino/normal/BadSample1.java

結果としては正しく表示されます。ループカウンタの開始の数字は別に0でなくてもいいしループ条件もループカウンタ<100でないといけないわけではありません。そこを直さずにループ内で補正しています。ループカウンタの数字を利用するのであればその数字を計算せずにそのままつかうのが良いように考えます。また、if文で評価するたびに+1するくらいであればそのような変数を持てばよいのでは?と考えます。

次に、if文の中での評価順を間違えているものです。
https://github.com/regtan/fizzbuzz/blob/master/src/org/kirino/normal/BadSample2.java

これは仕様を満たしていません。動かしてみるとすべての数字がそのまま出力されてしまいます。if文の評価式に問題があります。

if (i+1 % 3 == 0){
    System.out.println("Fizz");
}

ここの評価式ですが、1%3の部分がまず計算されるので1、次にi+1が計算されてから0と等しいかどうかを判定します。そのため、一番下のelseに入って数字がそのまま表示されるということが発生します。これは上で上げた例を目指して実装しようとして失敗している例です。直したところで上のような状態になるのではもうちょっと頑張りましょうというところです。

最後に細かい点ですがついでに変数名が大文字になってないか確認します。たまに大文字で変数書かれる方がおられます。Javaの経験があればこういう書き方はしないだろうなぁって程度に見るくらいです。あと、while(true)でループしてループカウンタが100の時breakするような処理をしていたらなんで?って突っ込み入れます。*1

ここまでできればOKな例

すなおに実装しているパターンであればOKです。
https://github.com/regtan/fizzbuzz/blob/master/src/org/kirino/normal/BasicSample.java

if(i % 3 == 0 & i % 5 == 0)

上の部分は3と5が互いに素であることから15で割った余りという判定でも良いでしょう。おとなしくループカウンタも1から100まで回るようになっていれば良いかと思います。ここでループ条件がループカウンタ<101であっても別にいいですが、その場で101にした説明を求めるかと思います。

判断が難しい例

golf的に短く書こうとしている場合です。
https://github.com/regtan/fizzbuzz/blob/master/src/org/kirino/normal/Sample.java
そのほか、セミコロンレスJavaとかJava 30byte FizzBuzz - プログラマーの脳みそを回答した場合も同様に判断に困ります。
これらの内容をコピペ的に覚えているだけの場合があるからです。その場合はそのコードに対してなぜそう書いたかを説明できるかどうかというところです。まったくもって説明できないのであれば問題ありと判断せざるを得ません。

もうひとつの出題方法

if文の中での評価順を間違えているものを正しく動くように直してもらうという出題形式もいいかもしれません。
https://github.com/regtan/fizzbuzz/blob/master/src/org/kirino/normal/BadSample2.java

まとめ

これがまったくできないから絶対採らないというわけでもありません。これで手も足も出ずにフリーズされるとちょっと不安になります。派遣さんで実装担当と紹介していただいた場合だと特に。現実としてすべての会社さんがそうではないのですが残念ながら下駄を履かせて紹介されることもあります。新卒やそうでない人たちであれば、これから学んでいこうという姿勢があれば別にできなくてもいいかなとも思ってます。

*1:forの使い方がわからないかもしれないから

Node.jsの環境を作ってうごかしてみる

タイトルとおまけの部分を追記しました

みなさんWEB+DB PRESS読んでますよね?

WEB+DB PRESS Vol.64

WEB+DB PRESS Vol.64

Vol.64にはももクロ界のスーパーエンジニアのぎゃんすー先輩(@sugyan)のNode.js記事が載っていますので写経しつつ環境を作っていこうとおもいます。

nvmのインストール

nvmってのはNode.jsのバージョン切り替えるツールとのこと。ぎっはぶにあるからcloneしてsourceすればおk。そもそもgitが入ってなかったのでこんな感じ。

//gitのインストール
# yum install git
//nvmをgithubからclone
$ git clone https://github.com/creationix/nvm.git
//nvmのディレクトリをdot化してsourceする
$ mv nvm .nvm
$ source .nvm/nvm.sh
//Node.jsのインストール
$ nvm install v0.4.10

はいここでエラー出ました。こんな感じ。

[reg@anko ~]$ nvm install v0.4.10
######################################################################## 100.0%
Checking for program g++ or c++          : not found 
Checking for program icpc                : not found 
Checking for program c++                 : not found 
/home/reg/.nvm/src/node-v0.4.10/wscript:232: error: could not configure a cxx compiler!

C++コンパイラがないようです。さっそくいれましょう。

//C++コンパイラのインストール
# yum install gcc-c++

Ubuntuだとbuild-essentialインストールすればいいみたい。ここまでやってもう一度実行。ちょっと時間がかかるけどビルドして自動的にインストールされます。おわったらデフォルトで利用するNode.jsのVerを指定します。

//デフォルトで利用するNode.jsのVerを設定
$ nvm alias default v0.4.10

ログインシェルにnvm.shを読み込むように設定しておけば超ハピラキ*1らしいのでついでに設定。.bashrcに以下の内容を追記。

source ~/.nvm/nvm.sh

ここまでできたらバージョン確認コマンドで正しいVer帰ってこればOK。

$ node -v

あとはぎゃんすー先輩の記事のサンプルコードを動かしてhello worldしてみるといいと思います。

まとめ

C++コンパイラさえ入っていればなんとかなる。あとは記事をよんで写経すればいいとおもいます。

おまけ

調子にのってnvm deactivateした場合はnvm use ver番号でPATHもMANPATHも元にもどります。

低スペックな頭の僕がhadoopの環境を作ってうごかしてみる

黄色い象さんでおなじみのhadoopですが正直のところあまりよくわかっていません。流石にそろそろまずいとおもうのでさっそく環境作って動かしてみます。今回は超ざっくりSingleNodeSetupのドキュメントを訳したりしながら進めます。

hadoopってなんぞ

hadoopのOverviewにはこんなこと書いています。*1

  • MapReduce*2
    • 超でっかいデータセット(テラバイト)を数千ノードのでっかいクラスタで分散処理を簡単に書くためのフレームワーク
    • データセットを分けて、バラバラに処理する
    • タスクのスケジューリングや失敗したタスクの再実行もする
  • HDFS*3
  • Common
    • File System Shell/Service Level Authorization/Native Libraries
    • サブプロジェクト見ろし

相変わらず僕の訳がひどいので原文みてくだしあ><Getting Startedに従ってSingle Node Setupをやってみます。

Single Node Setupをやってみる。

ドキュメントはこちらターゲットはOracle Virtualbox上のScientificLinux6.1を利用。

サポートしてるプラットフォームと必要なソフト

Linuxだったらdevelopmentとproductionをサポートするよ。windowsはdevelopmentのみサポートするよってことらしい。今回はScientificLinuxなのでとくに問題なさそう。必要なアプリはJava1.6とsshsshdが必須。windowsCygwinがいるよってことらしい。今回はScientificLinuxなのでJava1.6とsshsshdがあればおk。

インストール

ドキュメントを読むとrsyncもいるみたいなのでインストールします。

//rsyncインストール
# yum install rsync

ScientificLinux6.1にはデフォルトで入っているので必要なかったようです。ついでにJava1.6をインストールしましょう。openjdkでいいよね。

//openJDKインストール
# yum install java-1.6.0-openjdk

これでインストールするとランタイムしかインストールされません。開発環境をつけてインストールしたいのでjava-1.6.0-openjdk-develというパッケージを選びます。テヘペロ

//openJDKインストール
# yum install java-1.6.0-openjdk-devel

hadoop本体をダウンロードします。適当なディレクトリに移動して以下のコマンドを実行。

//hadoop本体のダウンロード
$ wget http://ftp.kddilabs.jp/infosystems/apache//hadoop/common/stable/hadoop-0.20.203.0rc1.tar.gz

展開したらこんな感じ

[reg@anko hadoop-0.20.203.0]$ ll
合計 6632
-rw-rw-r--.  1 reg reg  412413  5月  4 15:30 2011 CHANGES.txt
-rw-rw-r--.  1 reg reg   13366  5月  4 15:30 2011 LICENSE.txt
-rw-rw-r--.  1 reg reg     101  5月  4 15:30 2011 NOTICE.txt
-rw-rw-r--.  1 reg reg    1366  5月  4 15:30 2011 README.txt
drwxr-xr-x.  2 reg reg    4096  8月 24 16:46 2011 bin
-rw-rw-r--.  1 reg reg   97666  5月  4 15:30 2011 build.xml
drwxr-xr-x.  4 reg reg    4096  5月  5 00:00 2011 c++
drwxr-xr-x.  2 reg reg    4096  8月 24 16:45 2011 conf
drwxr-xr-x. 14 reg reg    4096  5月  4 15:30 2011 contrib
drwxr-xr-x.  7 reg reg    4096  8月 24 16:45 2011 docs
-rw-rw-r--.  1 reg reg    6842  5月  4 15:30 2011 hadoop-ant-0.20.203.0.jar
-rw-rw-r--.  1 reg reg 3471348  5月  5 00:00 2011 hadoop-core-0.20.203.0.jar
-rw-rw-r--.  1 reg reg  142469  5月  4 15:30 2011 hadoop-examples-0.20.203.0.jar
-rw-rw-r--.  1 reg reg 2285620  5月  5 00:00 2011 hadoop-test-0.20.203.0.jar
-rw-rw-r--.  1 reg reg  284888  5月  4 15:30 2011 hadoop-tools-0.20.203.0.jar
drwxr-xr-x.  2 reg reg    4096  8月 24 16:45 2011 ivy
-rw-rw-r--.  1 reg reg    9731  5月  4 15:30 2011 ivy.xml
drwxr-xr-x.  5 reg reg    4096  8月 24 16:45 2011 lib
drwxr-xr-x.  2 reg reg    4096  8月 24 16:45 2011 librecordio
drwxr-xr-x. 15 reg reg    4096  8月 24 16:46 2011 src
drwxr-xr-x.  9 reg reg    4096  5月  4 15:30 2011 webapps

Standalone Operationをうごかす

ドキュメント通りに動かします。展開したディレクトリに移動して以下のコマンドを実行

//inputディレクトリを作成する
$ mkdir input 
//confの下のxmlをコピー
$ cp conf/*.xml input 
//hadoopのgrepを実行
$ bin/hadoop jar hadoop-examples-*.jar grep input output 'dfs[a-z.]+' 

はい。ここでエラーがでました。

[reg@anko hadoop-0.20.203.0]$ bin/hadoop jar hadoop-examples-0.20.203.0.jar grep input output 'dfs[a-z.]+'
Error: JAVA_HOME is not set

おとなしくJAVA_HOMEを設定します。

//JAVA_HOMEの設定
$ export JAVA_HOME=/usr

これが終わった後に再度実行。

$ bin/hadoop jar hadoop-examples-*.jar grep input output 'dfs[a-z.]+'

ログが流れ終わったら終了なので結果を確認します。

$ cat output/*

こんな結果が返ってきました。

[reg@anko hadoop-0.20.203.0]$ cat output/*
1       dfsadmin

この文字列がヒットしてるみたい

[reg@anko input]$ grep -P dfs[a-z.]+ *.xml
hadoop-policy.xml:    dfsadmin and mradmin commands to refresh the security policy in-effect. 

Pseudo-Distributed Operationを動かす

疑似分散環境モードってことらしい。ドキュメントに従って設定ファイルを変更する。ドキュメント通りにやればおk。ssh周りの設定も一度sshでローカルホストにログインしておけばいい。まずはHDFSを初期化。hadoopを展開したディレクトリに移動してコマンド実行。

//HDFS初期化
$ bin/hadoop namenode -format

その次にhadoopデーモンを起動

//hadoopデーモン起動!
$ bin/start-all.sh

こんな感じで起動する。

[reg@anko hadoop-0.20.203.0]$ bin/start-all.sh 
namenode running as process 6092. Stop it first.
reg@localhost's password: 
localhost: starting datanode, logging to /home/reg/hadoop-0.20.203.0/bin/../logs/hadoop-reg-datanode-anko.localdomain.out
reg@localhost's password: 
localhost: starting secondarynamenode, logging to /home/reg/hadoop-0.20.203.0/bin/../logs/hadoop-reg-secondarynamenode-anko.localdomain.out
jobtracker running as process 6297. Stop it first.
reg@localhost's password: 
localhost: starting tasktracker, logging to /home/reg/hadoop-0.20.203.0/bin/../logs/hadoop-reg-tasktracker-anko.localdomain.out

namenode running as process 6092. Stop it first.ってのは失敗してた時のプロセスがのこってたから。
http://サーバー:50070/にブラウザでつないでNameNodeの状態が表示されることを確認して、http://サーバー:50030/につないでJobTrackerの画面が表示されることを確認できればおk。さっき作ったinputとoutputのディレクトリを空にしてコマンドを順に実行

//HDFSにインプットファイルをコピー
$ bin/hadoop fs -put conf input
//実行だじぇ!
$ bin/hadoop jar hadoop-examples-*.jar grep input output 'dfs[a-z.]+'
//outputファイルをコピー
$ bin/hadoop fs -get output output 
$ cat output/*
//デーモン停止
$ bin/stop-all.sh

結果はこんな感じ

[reg@anko hadoop-0.20.203.0]$ cat output/*
cat: output/_logs: ディレクトリです
1       dfs.replication
1       dfs.server.namenode.
1       dfsadmin

まとめ

正直、hadoopのおいしいところって複数のNodeで動かして初めて出てくるんじゃないかとおもったり。現にスタンドアロンで動かすより疑似分散環境のほうが遅く感じたわけで。やってる内容がちがうから何とも言えませんが。もうちょっとつづくんじゃよ。

低スペックな頭の僕がPOUNDでロードバランサ立ててみる

IT業界転職ブームですね。地豆んじゃーリーダーとその上司のお二方が転職されて新しい道を歩まれるとのことです。いやほんとおめでたい。

多くは語りませんがこういうことです。はい。というわけで今回はソフトウェアロードバランサのPOUNDのお話をしてみます。

POUNDってなんぞ。

http://www.apsis.ch/pound/のWHAT POUND ISってところ見ろし。

  • リバースプロキシだよ
    • クライアントからのリクエストをバックエンドサーバになげるよ
  • ロードバランサ
    • クライアントからのリクエストをセッション情報を保ったまま複数のバックエンドサーバに振り分けるよ
  • SSLラッパー
    • HTTPSを復号してバックエンドサーバにHTTPでなげるよ
  • HTTP/HTTPSサニタイザ
    • リクエストの妥当性を確認するよ
  • フェイルオーバーサーバ
    • バックエンドサーバが止まってたらそこにリクエストをなげないようにするよ
  • リクエストリダイレクター
    • URLに応じてリクエストをサーバに振り分けるよ

Webサーバやアクセラレータ*1ではないのとのこと。

インストール

とりあえず動かすためにインストールしてみます。ターゲットはOracleVirtualBox上に構築したScientificLinux6.1*2。なんでScientificLinuxかって?厨二的な何かだから気にするな。別にCentOSでもいいよ。今回はソースからインストールします。

//ソースを落としてきます
$ wget http://www.apsis.ch/pound/Pound-2.5.tgz

とりあえず最新のstableのVerを落としてきます。適当なディレクトリに展開しておきましょう。展開先に移動してconfigureします。

//こんふぃぎゃー
# ./configure --with-ssl=/usr/lib

とやっていると残念ながら失敗してしまいました。

Missing OpenSSL (-lcrypto) - aborted

OpenSSLのライブラリがないよー(';ω;`)となっていますので入れましょう。

//openssl-develインストール
# yum install openssl-devel

もう一回configureしてmakeします。

//こんふぃぎゃーしてmake
# ./configure --with-ssl=/usr/lib
# make

ここで痛恨のコンパイルエラーです。

[root@anko Pound-2.5]# make
gcc -DF_CONF=\"/usr/local/etc/pound.cfg\" -DVERSION=\""2.5"\" -DC_SSL=\""/usr/lib"\" -DC_T_RSA=\""0"\" -DC_MAXBUF=\""0"\" -DC_OWNER=\"""\" -DC_GROUP=\"""\" -DC_SUPER=\""0"\" -DC_CERT1L=\"""\" -g -O2 -pthread -DUPER -DNEED_STACK -DHAVE_SYSLOG_H=1 -pthread -I/usr/lib/include  -D_REENTRANT -D_THREAD_SAFE -Wstrict-prototypes -pipe   -c -o pound.o pound.c
In file included from pound.c:28:
pound.h:340: error: expected specifier-qualifier-list before ‘LHASH’
make: *** [pound.o] エラー 1

どうやらOpenSSLのVer記述が入っている場所に問題があるようです。Pound-2.6fではfixしているよ。*3とのことなのでPound-2.6fをコンパイルしてインストールします。

//ソースを落としてきます
$ wget http://www.apsis.ch/pound/Pound-2.6f.tgz
//適当に展開してこんふぃぎゃーしてmakeしてまでは一緒なので省略
# make install

とりあえず動かしてみる

簡単にこんな構成を作ってみた。

設定ファイルはデフォルトでは/usr/local/etc/pound.cfgにおいておけばOK。pound起動時の-fオプションで好きな場所を指定できる。超簡単な内容は以下の通り。

ListenHTTP
  Address 192.168.10.151
  Port 80
  Service
    BackEnd
      Address 192.168.10.154
      Port    80
      Priority 5
    End
    BackEnd
      Address 192.168.10.156
      Port    80
      Priority 4
    End
  End
End

ListenHTTPにはPOUNDが常駐するサーバIPとポートを指定。BackEndのところに振り分けたい先を書いておく。Priorityは数字が大きい方に優先して振り分けられる。詳しくはmanコマンドでマニュアル確認すると最後にフォーマットなどが出てくるので参照してくだしあ。ネットで検索する時はVerによって記述方法が違うのでその辺注意しましょう。*4

挙動の確認

バックエンドサーバにそれぞれ判別できるようなものをいれてPOUND起動したらブラウザでPOUNDが常駐してるところにアクセスしてF5連打したら振り分けられていることがわかる。ログは/var/log/messageに出力されるのでそこを確認してもよい。*5

まとめ

makeするときのエラーなんかがなければ20分くらいで設定までいけそうなかんじ。あればっかりは回避しようがないらしくおとなしくPound-2.6fを利用しました。ただlogの出力先の設定がどう解決したらよいものやらといったかんじ。

*1:もちろん学園都市にいるLv5のあの人のことではない

*2:http://www.scientificlinux.org/

*3:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=622041

*4:http://www.atmarkit.co.jp/flinux/rensai/apache2_05/apache05c.htmlの記事は古いから注意

*5:実運用でここに出してると結構アレな状況になるので要注意

アジャイルサムライぼっち道場その1

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

ちまたでアジャイルサムライが大人気なので流行に乗って読んでます。あんまりアジャイル経験がなくレガシーな開発スタイルばかり行っている僕でも簡単に読みすすめることができます。アジャイルラクティスよりアジャイルサムライのほうがより実践的に感じます。
各地でアジャイルサムライ道場という名の読書会をやっています。業務経歴書と履歴書もって某社に道場破りに伺うのも考えていますがとりあえず社内で他に読んでる人もいなさそうなのでぼっち道場したのをまとめてみます。

続きを読む

今すぐフォローすべきドンブリ界のスーパーエンジニア

@sugyanさん

twitterhttps://twitter.com/#!/sugyan

鎌倉にあるどんぶりカフェbowlsのMayer。bowls以外で晩ご飯を食べる方が珍しいくらいのドンブリ界のスーパーエンジニア。最近はJD*1と丼を食べているらしい。

*1:女子大生