2012年1月28日土曜日

読書日記「エンジニアとしての生き方」

著者のLife is Beutifulというブログからの記事と、雑誌などのコラムを編集した、主にエンジニアのキャリアについて述べられた本です。

実は私は学生の頃から中島さんのブログが大好きで、キャリアの意思決定などにかなりの影響を受けてきました。新卒で今の会社に入社したのも、中島さんのブログで英語の重要さや自分でブログラムを書くことの重要さを認識したという点がかなり大きな理由です。外資系の証券会社は外注ではなく殆ど社内で開発を行いますので。

彼のテクノロジーに対する真摯さやモチベーションの高さに感服すると同時に、以下のような彼の主張に強く共感し、影響されてきました。

  • どんなに優秀なエンジニアでも、決してプログラムを自分自身で書かずに良い詳細仕様を作ることは出来ない(プログラミングは知的な仕事であり、ITゼネコンの下請け構造では良いソフトウェアは作れない)
  • 会社人間ではなく真に価値のある人材になろう(社内だけではなく業界全体または社会全体で価値のある人材を目指すべきである)
  • 知的労働者には「組織を移る力がある」(自分のキャリアプランと日々の仕事をシンクロさせる)
  • 技術者にも必要な「儲ける決意」(技術者にも儲ける意識やビジネスセンスは重要)
  • 英語はグローバル人材市場へのパスポート


でも、僕の心に一番刺さったのはこの文章ですね。( Software is Beautiful「第1回 一生の仕事を選ぶということ」より引用)
せっかく職に就くのであれば,給料とか社会的地位とかを基準にするのではなくて,自分が好きなことやりたいこととマッチした職を選ぼう,というのが私の人生論である。若いうちにいろいろなものに触れておき,自分が本当に何がしたいのか,何になら夢中になれるのかをできるだけ早いうちに見つけ出すことはその後の人生にとって大きなプラスとなる。そんな「天職」を得るための努力なら惜しむことはないし,けっして無駄にはならない。そうやって「好きなことをして生きていく」ための努力を続けている限り,(ほかの人にとっては)つらいことも苦痛ではなくなるし,楽しい人生がおくれる。一度しかない人生,思いっきり楽しもうぜ。
この本を読んで、自分の好奇心に忠実に、常に全力で情熱を注げるできるような仕事をして生きていきたいと改めて感じました。

2012年1月27日金曜日

JSONICを使ってみる

ちょっとJavaでJSON形式のデータを扱う必要があったので、JSONICというJSON Parserを利用して見ました。JavaのライブラリではJSON-libというのが定番らしいのだけれど、他に依存するライブラリがあったりして面倒そうだったので、とりあえず一番シンプルそうなJSONICを使いました。

僕はFacebookのGraph APIで返ってきたJSON形式のデータをJavaのオブジェクトとして取り込みたかっただけなので、decodeだけ利用しました。使い方はとても簡単で、JSONのフィールドと対応する変数とaccesserを持ったクラスを指定してやるだけ。

まず、Graph APIはユーザの情報を以下のような形で返してくれます。

{
  "id": "123456789", 
  "name": "Foo Bar", 
  "first_name": "Foo", 
  "last_name": "Bar", 
  .....
}

で、以下のようにidとnameの変数とアクセッサを持ったクラスを定義してやります。

public class FBUser {
   private String id;
   private String name;
 
   public FBUser(){ }

   public String getId() {
      return id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   } 
}

そして、以下のようにJSONのデータとクラスの型を引数にしてdecodeを呼ぶと、勝手に個々のフィールドに値を入れてくれます。おそらく、リフレクションを使ってJSONのフィールド名からsetterの名前を推測しているのでしょう。例えばフィールドが'id'だったら'FBUser.class.getMethod("setId")'とかね。ちゃんとidとnameがログに出力されました。

String jsonFbUser = FBLoginUtil.getResponseFromURL(FBLoginUtil.getGraphApiUrl() + "me"  + "?access_token=" + accessToken);
final FBUser fbUser = JSON.decode(jsonFbUser, FBUser.class);  
log.info("id:" + fbUser.getId());
log.info("name:" + fbUser.getName());

このブログを書くよりは遥かに短い時間でオブジェクトとして取り込むとこまで出来てしまいました。オジサンの知らない間に世の中便利になってますな。賢い人達、いつもどうもありがとうございます。

2012年1月26日木曜日

gitを使ってみた

gitを使ってDropboxにレポジトリを作ってみた。ついでに、EGITをインストールしてEclipseからcommitとpushができるようにもしました。

最近、一人で開発を始めたのですが、ワークスペースが全部ローカルのMacに入っているので気持ち悪いと思い、Dropboxをレポジトリにしてgitを導入してみた。僕はsubversionしか使ったことないのですが最近の若者に流行りらしいのであえて。一番の違いは、serverで一元的に管理するsubversionとは対照的に、gitはすべてのコピーがマスタレポジトリのフルコピーを持っていて、ヒストリーの確認は勿論、コミットもできる分散レポジトリであるという点みたいですね。

とりあえず、Mac OS X 用のインストーラーがココにあるので、ダウンロードしてインストール。git help とコマンドを打ってみると、add/checkout/diff/commitなどsubversionで見慣れたコマンドが並んでいて一安心。

まず、user.name、user.emailをgit config コマンドで登録します。

git config --global user.name foo
git config --global user.email foo@bar.com

どうやらversion1.7.5からはレポジトリとワークスペースのディレクトリを別にする--separate-git-dirというオプションが追加されたようなのでDropboxだけでレポジトリを管理しようかとも思ったのですが、DropboxをマスタにしてLocalドライブを自分用にした方が分散レポジトリというgitの哲学に合ってるんじゃないかなぁと感じたのでそうしました。毎回マスタにPushするのはちょっと面倒かもしれないけど。


レポジトリを作るのはアホみたいに簡単で、Dropboxに適当なディレクトリを作って(e.g. $HOME/Dropbox/git_repos/MyProject.git)、そこにcdしてgit --bare init とコマンドを打つだけ。

僕はEclipseでGoogle App Engineのアプリケーションを書いているのでEGITというEclipseから使える管理ツールをインストールしました。subversionで言うsubclipseみたいなもので、ちょっと触ったところ使い方は殆ど同じなので、10分位でレポジトリ作ってcommitしてDropboxにpushするところまでできてしまいました。試しに、マスタレポジトリからgit clone で適当なディレクトリにコピーしてみたらちゃんとディレクトリ構造がコピーされました。Dropboxはディレクトリごとに他のユーザと共有とかできるはずなので、$HOME/Dropbox/git_repos/MyProject.git を他のユーザと共有すればマスタリポジトリの共有も出来ますね。

今回の作業では以下のページを参照しました。どうもありがとうございました。
Subversion ユーザーが Git を使ってみた (基本操作編)
Dropboxを利用してGitのプライベートリポジトリをつくる方法
git 1.7.5で追加されたオプションを使ってgit on Dropboxの運用を見直す
EGit/User Guide

2012年1月16日月曜日

読書日記「Web開発者のための 大規模サービス技術入門」

株式会社はてなの伊藤さん(現GREE)と田中さんという、Webに興味のある人なら名前くらいは聞いたことがあるだろう人達の書いた、「Web開発者のための 大規模サービス技術入門」というその名の通り大規模なWebサービスをどう運用していくかを説明している本です。理論的な説明だけではなく、実際にはてなで使われている運用方法などの「泥臭い」部分をかなり詳しく説明してくれているとても実践的な本でした。

この本を読んで、もし自分で大規模サービスを運用が必要になる時には絶対に自分でインフラは持たずにGoogle App Engineのようなクラウドサービスを使おうと思ってしまいました。さすがに自分でここまでする気にはならないですね…。

基本的にはパフォーマンスの問題はCPUかI/Oのどちらかがボトルネックになります。そういう時は単順にtopやsarでどちらの問題か切り分けます。どのプロセスがCPUをどれくらい使ってるかとかI/Oの待ち時間がどれくらいあるのかとかを確認すれば、だいたい目星はつくでしょう。

CPUがボトルネックの場合は以下のような解決方法があります。単純に計算量が足りないだけなので、比較的解決は簡単なようです。
  • サーバを増やして処理を分散させる。この場合はDBと違ってデータのレプリケーションなども必要無いので、比較的簡単にスケールする。
  • アルゴリズムを改善して計算量を減らす

I/O側はCPUのように、サーバの台数を増やすだけでは簡単にスケーリングできないので対応が難しいようですね。Googleが独自の分散ファイルシステムやデータベースを持っているのもそれが理由でしょう。対応の仕方としては以下の方法があるそうです。
  • できる限りキャッシュやメモリのヒット率を高めてディスクアクセスがないようにする。(メモリはディスクアクセスの10万倍以上高速)
  • プログラム変更でメモリの利用が減らせるならそうする。
  • 足りなければメモリを増やす。できないならデータを複数サーバに分散させる。
  • データベース側のスケーリングをする(最終手段)。マスタDB(書き込みを担当するDB)のスケールアウトはACIDが求められるため難しいが、テーブル毎やエントリー毎に別サーバにデータを分散させるようなトリッキーな事をすることもあるようです。TwitterもMySQLの分散とmemcachedで運用しているみたいですね。

RDBの分散やデータの圧縮の話はとても面白いと思いました。RDBのデータを分散するのにテーブル毎に別サーバに分散させたりするので(勿論できるだけ局所性を保つように分散する)、INNER JOINを使わずに複数回クエリを投げるプログラムを書いたりするらしいです。もはや、RDBではないですね。

他にも、データ圧縮をI/Oを減らすためだけとかに使ったりとか、データをページキャッシュにのせるためにアプリケーションで使われる大規模データを一度catしたりとか、面白いノウハウが載っていました。そういえば、僕のサポートしているシステムでもデータをキャッシュに入れるために、再起動するたびにウォームアップさせてるなぁなんて思いながら読みました。

後半のインフラ系の話の部分はまだ読めていないので、また後日にでも。ちらっと見た感じ、SSDを使った高速化とか面白そうだな。明日、Macbook Airが届く僕としては…

2012年1月7日土曜日

読書日記「Webを支える技術-HTTP、URI、HTML、そしてREST 」

ちょっとWeb系の技術の基本的な部分を勉強してみようと思って、「Webを支える技術」という本を読んで見ました。RESTfulな設計の大切さ、URIとHTTPの説明、ハイパーメディアフォーマットなどのWebに使われている基本技術の説明がメインで、最後に少しWebサービスの設計例が載っています。僕のような、コンピュータの基本的な知識はあって、勿論HTMLやJavascriptはある程度書いたことはあるけれども、体系的に勉強した経験がないような人間に丁度よい本でした。

本書ではRoy Fieldingが提唱したREST(Representational State Transfer)というWebのアーキテクチャースタイルを良しとしており、URI(リソース)、HTTP、ハイパーメディアフォーマットについて説明すると同時に、いかにそれらをRESTfulに利用するかについても言及しています。本書では、以下の6つの制約を合わせたアーキテクチャースタイルがRESTであり、実際のアプリケーションは必要に応じていくつかの制約を除外しながら実装すれば良いと述べています。

  1. クライアント/サーバ
  2. ステートレスサーバ
  3. キャッシュ
  4. 統一インターフェース
  5. 階層化システム
  6. コードオンデマンド

個人的には一番印象に残ったのはMethodの説明です。僕が学生時代にWebを少しかじった頃はちょうどSOAPが出てきた頃で、たしかSOAPで実装されたGoogleのWeb検索APIとかで遊んだ記憶があるのですが、今は完全にRESTに基づいてHTTPメソッドを使い分けるのが主流のようですね。5年前の僕がしていたPOSTだけですべての処理をこなすなんていう処理は完全なるアンチパターンのようですね。HTTPには以下の8つのMethodが用意されており、個々の役割は決まっているので用途に応じて使い分けるべきらしいです。
  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • TRACE
  • CONNECT

後はHTTP、URIやデータフォーマット(HTML、JSON、microformats、Atom)の説明や、通信プロトコル、ヘッダー、ステータスなどのリファレンス的な情報などの説明もあり、基本的な技術をおさらいするのにはとても便利でした。


2012年1月5日木曜日

ソーシャルゲームで遊んでみた

MobageやGREEなどのソーシャルゲームが流行っているようなので、どのようなものかと興味本位でちょっと遊んで見ました。とりあえず、以下にリストアップしたものをチョコチョコやってみました。

Mobage
怪盗ロワイヤル
忍者ロワイヤル
大熱狂プロ野球カード

GREE
FIFA
ドリランド
Gantz
クリノッペ

どれもゲームシステムはかなり似通っているという印象を受けました。どのゲームもガチャでカードを入手して、ミッション(クエスト)でレベルを上げたり、他のプレーヤーとバトルをするという楽しみ方ですね。で、ガチャとアイテムの課金で収益をあげると。これ、上手くやったらソーシャルゲームフレームワークみたいなものを作って、中身のコンテンツを差し替えるだけで色々なゲームが作れるようになってしまうのではないだろうか。ていうか、もうあるのかもね。少なくとも、コードの大部分は使いまわせるはず。

以下、キーワードの説明。

カード
「ガチャ」でカードを入手。無料ガチャと有料ガチャがあり、だいたい一回100円(ノーマル)か300円(レア)でガチャれる。各カードには攻撃力、防御力などのパラメータがある。基本的にはレアカードの方が強い。カードは合成して強くしたりもできる。

ミッション(クエスト)
基本的には「ミッションの実行」というボタンを押していると、カードを入手したり、レベルが上がったりする。たまにボスなどとのバトルになったりもする。実行するたびに行動ポイントを消費して、それがなくなると数時間回復を待つ、もしくはアイテムを使って回復できる。

バトル
他のプレイヤーとバトルができる。勝つと相手のアイテムを奪える。ボスバトルなどでは他のプレーヤーと協力して戦うこともできる。殆どのゲームではバトルは勝手にコンピュータが行う。バトルではチームメンバーの選択や配置などの戦略的な要素もそれなりにあるのだが、バトルの中身はスキップして結果だけを表示するゲームも多数あります。

アイテム
消費したパラメータを回復するアイテムとか、宝を守るアイテムとかがある。100円くらいで買える。

ゲームシステムがここまで似ていると、レアカードを強くしたりアイテムを集めたりというコレクション的な要素で差をつけるんでしょうね。後はユーザ間のコミュニケーションなどもアクセントになっていると思うのだけれども、そこまではやりこめませんでした。