2013年10月8日火曜日

ボイジャー太陽圏ででたよ

こんにちは。
LTといえば普通は技術紹介、気になるサービス紹介が普通でしょうが
私はあさっての方向の紹介担当です。

たまには宇宙に思いを馳せましょう。

2013年8月12日月曜日

第3回、合同勉強会を開催しました



はじめまして。技術チームのガブです。先日、第三回合同勉強会を弊社オフィスにて行いました。ビールやソフトドリンクを飲みながら、六名のすばらしいエンジニアの方々から、高度にテクニカルなお話を二十分間、楽しく伺うことができました。発表者の皆様を始め、今回の勉強会のために貴重なお時間と労力を割いていただいた方々に深く感謝いたします。

各プレゼンの模様を簡単にご紹介いたします。


1. 今村 雅幸 (株式会社Vasily CTO)さん





今村さんには、急増するユーザーに対応するべく、アプリケーションをスケールするテクニックをテーマに講演していただきました。やはり、VasilyのようなBtoCの場合、ID数の増加が急激すぎてやばいですね。スライドを見ていてゾクゾクしました。僕たちも早く新しいサービスでこんな悲鳴を上げてみたいです。ちなみにVasilyさんの場合、tumblrのinboxモデルを参考に独自の実装をされていました。tumblrのarchitectureについてはこの記事なんかが参考になります。


2. 林 孝之さん



林さんには今回、ごく少数の人に知識や情報が集中せずに生産性を上げていく一つの解として、ペアプログラミングについて発表していただきました。
僕は今、実際にペアプロをやっていますが自分で書いたコードよりも明らかに美しく、読みやすく、バグの少ないコードを書く事が出来ています。林さんがプレゼン中に言っていた、「ペアプロじゃないと怖くてコードを書けない」という事を実感します。一方で、相方とのスキル差が絶望的にあり(僕が低い方です... )、とても疲れるし、理解できていないまま進んでいってしまう時があります。この辺りの課題をどうするか、林さんに改めて質問してみたいなと思います。




3. 津留 一仁 (株式会社マインドパレット リベロエンジニア)さん


津留さんにはAngularJSの特徴、ユースケースについて、プレゼンしていただきました。
Gitコマンドをバシバシ叩きながら、分かりやすいサンプルデモをいくつも交えて発表していただき、(皆さんに共通しますが)とてもイメージしやすく素敵なプレゼンでした。
AngularJSはHTMLそのものがテンプレートである事や、パイプラインで検索フィルターを追加できる事(すごく簡単そう)など、簡単に始められて便利な機能満載。開発していて楽しい感じが伝わってきて思わずダウンロードしてしまいました。




4. 竹内 秀行(ユーザベース)さん


竹内さんのトピックは、みんな大好きDynamoDBの解説です。前々回、株式会社マインドパレットの神尾さんにSimpleDBの恐ろしさを存分に教えていただいた僕たちは、「SimpleDB、ダメ、ゼッタイ」を合い言葉にDynamoDBを採用する事にしました。そんな訳で今回、DynamoDBの素晴らしさを皆さんにお披露目する場になりました。例えば、DynamoDBのキャッチフレーズの一つに「支払いは実際に使用した分だけ。最低料金は不要です。」というものがあります。素晴らしい!さすがAmazon先生!ところが実際の料金プランを見ていくと、事前に利用枠を買って使うというこの矛盾!世の中そんなに単純じゃないんだぜ!という先生からのメッセージを胸に、僕たちはまた一つ大人になったのでした。



5. 加藤じゅんいち(id:j5ik2o)さん


加藤じゅんいちさんは、Domain Driven Design(DDD)について、お話していただきました。最近、僕の入っているプロジェクトではTDDを始めていますが、DDDの基本的な考え方であるドメインモデルを中心に設計していけるとコードがすごくキレイになります。抽象化と共通化が適切にできる事に感動するとともに、今まで自分が書いたものは何だったのかと小一時間(ry
ただ、まだまだプレゼンしてもらった世界には全然到達できていないので、ご推薦のを買って読もうと思います。



6. 矢野勉 (代表取締役 株式会社シェルフ)さん



Lispには括弧が多すぎる。

矢野さんのプレゼンはそんな風にして始まりました。
そうしてClojureをおもしろおかしく説明した後で、唐突に矢野さんは言いました。
「これで皆さんは明日からClojureが書けますね。もう知らないなんて言えないですよ」
動揺する会場。微笑みの矢野さん。
会場からの「結局、括弧多くないですかClojure」「そのサービス、Railsならすぐ作れるんじゃないですか(Clojure生産性低くないですか)」という優しいコメントに矢野さんは「括弧の種類がいっぱいあれば読みやすいから問題ない!」、「Javaの資産がそのまま使えるから生産性は超高い!」とClojureへの愛とモヒカンぶりを遺憾なく発揮し、万雷の拍手を浴びておりました。
僕はそんなロックな矢野さんが大好きです!








上記のメインプレゼンの間に、懇親会とライトニングトーク大会も行いました。

板倉さん、荒井さん(Vasily)、長澤さん(UB)、石橋さん(UB)、加藤さん(UB)にLTを行っていただきました。

次回、第4回合同勉強会は10月頃に行う予定です。


ご興味のある方は是非ご参加ください。スピーカーの方も大募集中です。

連絡先はこちらです:technology@uzabase.com

2013年5月23日木曜日

世界最大の素数とその見つけられた方法

こんにちは。
LTにて、ほかの方は最新技術など面白いものを紹介してくださるので
私はあさっての方向の紹介を担当しようと思います。



ユークリッドの補題

スライドの中で何の断りもなく登場することの補題ですが、意味は
正の自然数nが素数pで割り切れ
n = ab (a > 1, b > 1)と分解できるとき、pはa, bの内の少なくとも一方を割り切る。
というものです。

「0がn個続いたあと1がn個続く」を正規表現にできるか?

こんにちは。前回に引き続きたぬきです。
週次LTの担当ということで、計算機科学の基礎を紹介してみました。

切り口として、正規表現まわりをやってみることにしました。Uzabaseは情報プラットフォームサービスSPEEDAを展開しており、どのエンジニアもデータベース周りの知識を持っているため、正規表現は慣れ親しんだものの1つであるからです。

具体的な問題として、「0がn個続いたあとに1がn個続く」を正規表現にできるか?をテーマとしました。

お話の流れとしては、(1) 正規表現は有限オートマトンに変換可能、(2) 有限オートマトンには必要条件がある、(3) 上述の問題は有限オートマトンの必要条件を満たさず、正規表現にはできない、という流れです。

ポンピング補題
オートマトンの復習および「(1) 正規表現は有限オートマトンに変換可能」については、文章よりスライドを見てもらえば十分かと思いますが、「(2) 有限オートマトンには必要条件がある」「(3) 上述の問題は有限オートマトンの必要条件を満たさず、正規表現にはできない」については口頭で話した部分を補足したいと思います。

(2) 有限オートマトンの必要条件のひとつに、ポンピング補題というものがあります。ある有限オートマトンの状態数をpとすると、そのオートマトンに認識される(受領される)文字列のうちp以上の長さの文字列は必ずポンピング補題の3条件を満たします。

条件のうちの1番目「各i≧0についてx(y^i)z∈A」についてもう少し意味を補足しましょう。まずAはある有限オートマトンが認識する(受領する)文字列の集合です。また、x(y^i)zとは、文字列xの後に文字列yが0回以上繰り返し続き、最後に文字列zがあるということです。つまり、1番目の条件は、ある有限オートマトンに認識される文字列は必ず、x(y^i)z∈Aを満たす文字列x, y, zにわけられるという意味になります。

ポンピング補題の証明は、スライドに記述した迷路のような図でも直感的に理解できるかもしれませんが、より詳しい証明は後述の本を御覧ください。

さて(3)に入り、「0がn個続いたあとに1がn個続く」がポンピング補題を満たすか調べてみましょう。もし「0がn個……」を満たす有限オートマトンがあるとすれば、その条件を満たす文字列で長さp以上のものはすべてポンピング補題を満たすはずです。

ここで、0がp個続いたあとに1がp個続く文字列sを考えてみましょう。sは明らかに「0がn個……」を満たします。またsは長さp以上なのでポンピング補題も満たすはずです。つまり「各i≧0についてx(y^i)z∈A」も満たすはずですが、どんなyならばそんな条件を満たすでしょうか?

実はその条件を満たすyは存在しません。もしyが0からだけ成るとすると、i≧2では文字列に含まれる1の数よりも0の数が多くなってしまい、Aに含まれることができません。yが1からだけ成るとしても同様です。あとはyが0と1から成った場合だけですが、この場合、yが連続すれば0の前に1が出てきてしまうため、やはりAに含まれることができません。よって、いかなるyも条件を満たしません。

以上のことから背理法により、「0がn個……」は有限オートマトンでないことが示されました。よって「0がn個……」は正規表現にできません。

まとめ
LTの時間的な制約から正確な定義などを説明せずに話を進めてしまいましたが、正確な定義や証明を理解していくと、とてもシンプルかつ奥深い世界に触れることができます。スライド内でも簡単に紹介していますが、下記の本がオススメです。

2013年3月29日金曜日

第二回、合同勉強会を開催しました

はじめまして。
技術チームのたぬきです。

先日、外部の方をお招きしての合同勉強会の2回目を、弊社オフィスで行いました。
社内外から5名のスピーカーにご登壇いただきました。

今回はオーディエンスとしても社外の方が参加してくださいました。
前回ご登壇いただいた株式会社マインドパレットの神尾さんは社内の方と4名でご参加、アイエント株式会社の西王地さん、某巨大BtoCサービスインフラチームリーダーのMr. Xさん(大人の事情でご紹介できません)にも来ていただけました。
だんだんと勉強会らしくなってきていますね!

以下、プレゼン資料と当日の様子を御覧ください。

1. Hazelbeck Gregory(ユーザベース)
Wikipediaのダンプデータとそれを使えるサービスについて。自然言語処理で博士論文を書いたGregさんの本領発揮といったプレゼンでした。


2. 西川真五さん(株式会社エムティーアイ
アジャイル開発手法のひとつscrumについて、実際に運用されている経験と共に説明していただけました。






3. 川口浩司(ユーザベース)
前職で扱っていたXMLデータベースについて良いところ・悪いところを詳しく解説。川口さんが一線でやってきた内容だけあって、現実感がよくわかる内容でした。

4. ????さん(某大手ITコンサルティング企業)
大人の事情で公開できません。が、とても未来的で興奮する内容でした。公開できないのが悔しい……。


5. 石橋隆平(ユーザベース)
コードの再利用について、あるべきと、どうしてそれができないか、どうすればできるかを解説。石橋さんのダークな部分がチラリ。


勉強会の後は、同じ会場でピザやお寿司をいただきながらのライトニングトーク大会!
技術的に面白い話も、☓☓的に面白い話もたくさんで、とても盛り上がりました。弊社チーフテクノロジストのたけうちさんは大富豪プログラミングについて発表。


本人注)当たり前のことを大まじめに酒の席でのたまわるというLTです

ユーザベース技術チームでは今後も定期的に勉強会を行います。
ちょっと聞いてみたい、と思った方はお気軽にご連絡下さい。
もちろんスピーカーとして来ていただける方も大歓迎です。

連絡先はこちら: technology@uzabase.com

次回は6月くらい……かな?

2013年2月15日金曜日

Ractive Programming

chimerastです。

週次LTの担当ということで、Reactive Programmingというパラダイムについて紹介しました。


Reactive Programming from Hideyuki Takeuchi

今流行りの関数型プログラミング言語では、Reactive ProgrammingというとFRP (Functional Reactive Programming)の事を指すことが多いのですが、そっちの説明を始めると若干複雑で前提として必要な知識も多くなるので、大元にある考え方にのみ焦点を当てました。

Reactive Programmingとは


JavaやRuby等の命令型プログラミング言語では

a = 10
c = a + 2
a = 1
print c

というようなプログラムがあった場合、12が出力されます。

これが、Reactive Programmingでは、cが出力される際にa+2という式が初めて評価され、3が出力されます(他の実装として、2行目ではちゃんとcに12を入れておいて、3行目のa = 1が実行されたときにcを再評価して3を代入するというものもあり得ます)。

現実にある実装


Reactive Programmingを体現した一番身近な言語(?)として、Excelがあります。
例えば、E1のセルに「=A1+A3」が入力されていたとして、A1やA3の値を変えると自動的にE1のセルも変わりますよね。

他にもFlexのMXMLにおけるデータバインディング式や、ちょっと違うかもしれませんがJavaFX(ScalaFX)もReactive Programmingが出来ると言っても良いと思います。

どういうところで便利か?


ロボット工学や、シミュレーション等いろいろと応用は効きますが、普通のプログラマにとっては上記のようにGUIプログラムで利用するというケースが一番効果が出やすいと思います。

例えば、コンボボックスが選択された時にその値に応じてテキストラベルを変えるようなプログラムをJavaもどきで書くと、

comboBox.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent event) {
    label.text = indexToText(comboBox.index);
  }
}

というように長々と、何をやっているのか本質がぼやけてしまうプログラムとなってっしまいます。
これをReactive Programming的な書き方をすると、

label.text = indexToText(comboBox.index);

の1行で記述できてしまいます。読み方を知っていれば何をやりたいのかも非常に明確です。

これは非常に簡単な例ですが、入力に複数のコンボボックスが関わってきたり、連鎖的に複数のコンポーネントの値が変わるようなものを作る場合には、Java等で書くときとくらべて非常に簡潔に記述することが出来ます。

まとめ


Reactive Programmingを直接利用できる言語や環境はあまりないですが、この考え方を知っていると、データには流れがあるんだという事が理解でき、機能としてReactive Programmingを利用できないような言語でもプログラムの書き方が変わってくると思います。

コマンド実行結果のログ取得について

k-kawaguchiこと川口と申します。
Linux等でのコマンド実行結果のログ取得方法について、LTで発表しました。


2013年2月6日水曜日

ネットワークについて

k-kawaguchiこと川口と申します。
技術チーム定例社内研修会にて、ネットワークについて発表しました。


2013年1月11日金曜日

Web RTC

UZABASEのYakopeliです。

2012/12/19に社内で行ったLTの内容になりますが、今回はWeb RTCについて調べてみました。


Web RTCとは

Real time Communication Beween Browsers APIの略で、JSを使用して
Webブラウザから端末のカメラやマイクにアクセスし、他のWebブラウザとの
リアルタイムなコミュニケーションを可能とするものです。

今までは音声やビデオのリアルタイムな通信を行うには専用のクライアントソフトが必要でした。
また、Webブラウザからは、プラグイン等を入れない限り、マイクやカメラなどのデバイスを
利用することはできませんでした。

しかし、Web RTCが普及すると、

・Webブラウザ上で実行されるJavaScriptで、端末のマイクやカメラなどの
 デバイスにアクセスできるようになる

・取り込んだ音声や動画をリアルタイムに他の端末のWebブラウザに送り、
 ストリーミング再生が可能になる

よって、Webアプリケーションにカメラやマイクを利用した、新しいリアルタイムな
コミュニケーション機能を組み込むことが可能になります。


Web RTCのアーキテクチャ

アーキテクチャですが、大きく分けると4要素で構成されています。

・Web API
 Webアプリケーション側から利用するためのAPI

・Session management/Abstract signaling
 セッション管理やP2Pマッチングの仕組み

・Audio/Video Engine
 オーディオ・ビデオ

・Transport
 データ転送の仕組み

上記のうち、Webアプリ開発者にとって大きく関係するのはWeb APIですが、これは単一の
APIではなく、主に下記二つのAPIから構成されます。

・Stream API
 映像や音声などのストリームデータを扱うAPI

・Peer-to-peer connections
 UDPプロトコルを用い、ブラウザ同士でダイレクトにデータを送受信するためのAPI

簡単に言うと、Stream APIでカメラやマイクにアクセスし、映像や音声をPeer-to-peer connectionsを使って互いのブラウザに送ると、テレビ電話みたいなものが作れます。


デモ

サンプルがあるので、デモで確認してみます。
http://apprtc.appspot.com/にアクセス後、画面下部に表示されるURLに別のブラウザから
アクセスするとテレビ電話が始まります。(どちらの端末もWebカメラが有効になっている必要があります)

まとめ

セキュリティ関連がどのように進められていくか気になるところですが、WebRTCによって専用のクライアントソフトを入れることなく、Webサイトを通じて音声や映像の通信ができるようになるので、何か新しいサービスが生まれてきそうな予感がしますね。


2013年1月7日月曜日

アルゴリズムって何だ


私はさんさです。

アルゴリズムとはよくいわれるものの、それって実際どんなものだ

そんな勉強会を先日開きました。

アルゴリズムとは

Al Khwarizmiというイラクらへんの人が由来。
彼は科学者であり、数学、天文学などの多くの分野において業績を残したそうだ。
ちなみに「アル」はアラビア語の定冠詞である。アラビア語由来の単語に「アル」で始まる物が多いのはそのため。他にも
  • アルデバラン (Aldebaran)
  • アルタイル (Altair)
  • アルカイダ (Al Qaeda)
  • アルジャジーラ (Al Jazeera)
  • アルコール (Alcohol) 英語発音はアルコホールである、注意しよう

現在の用法

もっぱらコンピュータ業界で念仏のように唱えられるアルゴリズムだが、辞書によると
  1. もとは算用数字を用いた筆算のこと
  2. 計算や問題を解決するための手順、方式。特にコンピューターのプログラムに適用可能な手続き
出典 三省堂 大辞林
コンピュータでは適切な解を得るための手順を意味することが多い。
数学でもユークリッドの互除法や、エラトステネスの篩(ふるい)なんかは聞いたことがあったとしたら、それもアルゴリズム

よいアルゴリズムとわるいアルゴリズム

一般的によいアルゴリズムと呼ばれるのは以下の条件を満たしていることが多い。いや、満たしているべきだ。
  • 意図する結果が得られること
  • 計算時間、計算量が少なくすむこと
  • 同じ作業の繰り返しでできること
  • 使い方が限定されないこと
とりわけ重視されるのが計算時間、計算量が少なくすむことであり、この指標としてO記法なんてものが使われる。

O記法(オーダー記法)

ランダウの記号なんて別名があったりするが、ドヤ顔でいっても何もならない。実行されるアルゴリズムが、どれほどの時間、記憶領域を使用するかを評価するものである。
よく見るのは
  • O(1)
  • O(n)
  • O(n2)
  • O(n * log2n)

Oってどうやって求めるの

難しい話はさておき、このオーダーってどうやって求めるの?という話、なんと以下のようにするだけでできるのである。
  1. 計算量を示す式の最大次数に着目する
  2. 最大次数の係数を無視する
  3. Oとカッコをつけてやる
例:(1/6)(2n3 + 3n2 + n)という計算量があったとする
ちなみに自然数の二乗の値のnまでの和の式である。
  1. (1/6)(2n3) ... 最大次数以外はいらない
  2. n3 ... 係数はいらない
  3. O(n3)
最大次数などという呼び方をしたが、実際には計算量の中で一番増加の割合が大きなものを示したものともいえる。

ソート

アルゴリズムの例として挙げられるものといえばソートそれだけ種類が多く、計算量にも違いがあるからだ。
ここでは以下のソートについて、計算量やアルゴリズムを交えて説明する。
  • バブルソート
  • マージソート
  • クイックソート
  • ボゴソート

バブルソート

隣接交換法なんて名前がある。 一般人にトランプを渡して番号通りになるようにソートして、というとたいていこれか選択ソートをする、というぐらい誰でも思いつきそうな一般的なソート。
  • 平均計算時間はO(n2)
  • 安定ソート
安定ソートが何かわからないあなたはwikipedia。 アルゴリズムは単純明快である。
  1. n番目の要素が、n + 1番目より大きければいれかえる
  2. 1.を最初から最後まで行う
  3. 2.を要素の数だけくりかえす
コードにするとこんな感じ
var bubbleSort = function(numbers) {
    var i = 0;
    var j = 0;
    var length = numbers.length;
    var temp = 0;

    for(i = 0; i < length - 1; i++) {
        for(j = 0; j < length - i - 1; j++) {
            if(numbers[j] > numbers[j + 1]) {
                swap(numbers, j, j + 1);
            }
        }
    }
};
隣り合う要素の交換が行われるため、隣接交換法と呼ばれたり、大きな数字が右側に移動していくさまが泡のようだからバブルソートなんて呼ばれているわけである。

マージソート

要素を分割、統合しながらソートする。安定した早さでソートできる。
  • 平均計算時間はO(nlog2n)
  • 分割、統合のしかた次第で安定ソートになる
  • javaのソートはこれを使用している
アルゴリズム
  1. 要素をn分割する(一般的にはn = 2)
  2. 1. を繰り返し、分割できなくなるまで分割する
  3. それらをマージする。マージの際にソートする
ただし、このソートには弱点があり、一時的に配列を別の場所に記憶しなければならない。
速度はそこそこである一方、記憶領域は消費するソートといえる。
var mergeSort = function(numbers) {
    var sort = function(start, end) {
        var i = 0;
        var j = 0;
        var k = 0;
        var temp = [];

        if(start >= end) {
            return;
        }

        var mid = Math.floor((start + end) / 2);
        sort(Math.floor(start), mid);
        sort(mid + 1, Math.floor(end));
        for(i = start; i <= mid; i++) {
            temp[i] = numbers[i];
        }
        for(i = mid + 1, j = end; i <= end; i++, j--) {
            temp[i] = numbers[j];
        }
        i = start;
        j = end;
        for(k = start; k <= end; k++) {
            if(temp[i] <= temp[j]) {
                numbers[k] = temp[i];
                i++;
            }
            else {
                numbers[k] = temp[j];
                j--;
            }
        }
    };
    sort(0, numbers.length - 1);
};

クイックソート

その名の通り早いソート、ただし弱点があり、遅くなるとバブルソートと大して変わらない。
  • 平均計算時間はO(nlog2n)
  • 安定ソート*ではない*
アルゴリズム
  1. 要素の中から基準値を決める(ピボット、要素数/2番目の値が選ばれることが多い)
  2. 基準値より左側に小さい値を、大きい値を右側に入れ替えるように移動する
  3. 1., 2.を再帰的に繰り返す
このアルゴリズムの説明よりも、コードを見た方が早いと思う。
var quickSort = function(numbers) {
    var sort = function(start, end) {
        var pivot = numbers[Math.floor((start + end) / 2)];
        var i = start;
        var j = end;

        while(true) {
            while(numbers[i] < pivot) {
                i++;
            }
            while(pivot < numbers[j]) {
                j--;
            }
            if(i >= j) {
                break;
            }
            swap(numbers, i, j);
            i++;
            j--;
        }
        if(start < i - 1) {
            sort(start, i - 1);
        }
        if(j + 1 < end) {
            sort(j + 1,end);
        }
    };

    sort(0, numbers.length - 1);
};

ボゴソート

とにかく遅くてダメなソート。バブルソート以下。
一般人にトランプを渡して番号通りになるようにソートして、といっても誰もやったことがないほどのソート。
  • 平均計算時間はO(n * n!)
  • 安定ソートではない
アルゴリズム
  1. 要素をシャッフルする
  2. 要素がソートされていたら終了、されていない場合は1. をくりかえす
ソートしろといっているのにいきなりシャッフルするのがこのソートのすばらしいところである。
var bogoSort = function(numbers) {
    var shuffle = function(array) {
        var i = 0;
        var length = array.length;

        for(i = 0; i < length; i++) {
            var pos = Math.floor(Math.random() * (array.length - i)  + i);
            swap(array, i, pos);
        }
    };

    var isAscending = function(array) {
        var i = 0;
        var length = array.length;

        for(i = 0; i < length - 1; i++) {
            if(array[i] > array[i + 1]) {
                return false;
            }
        }
        return true;
    };
    var sort = function() {
        while(true) {
            if(isAscending(numbers)) {
                return;
            }
            shuffle(numbers);
        }
    }

    sort();
};

グラフで見る

計算量をグラフで比較するとこんな感じである。
縦軸がy, 横軸がxとなってしまっているが、件数xが増えるとどのぐらい計算量の目安が増えるかというのがよくわかる。
特にボゴソート(赤線)、君は真っ先に天を目指しすぎだ。

ソートをグラフィカルに見る

Jsdo.itにヨサゲなソートをしてくれるものがあったので紹介。
http://jsdo.it/norahiko/oxIy/fullscreen
ボゴソートのクソっぷりを満喫してほしい。
今回はここまで