読者です 読者をやめる 読者になる 読者になる

pixivのインターンに行ってきた話

8/31~9/11まで、pixivのインターンシップ、「pixiv 2015 SUMMER BOOT CAMP」に参加してきました。 以下はその体験記です。

参加するまで

実は当初はてなインターンに参加を検討していました。 ですが、大学の課外授業が被っているせいでこれは諦めることに。 他社のインターンで面白そうなところを検討したところ、2週間という比較的長めの期間、 体験記を調べてみて面白そうだったこともありpixivに応募してみると通ったという経緯がありました。 交通費宿泊費が会社負担というのも大きかったです。

業務内容

主にスマートフォンアプリの開発をやりました。 初日に一班6人程度の班に別れ、(計4班)10日間に渡ってアプリの企画、開発を行いました。 チームの内訳は一般職2人+エンジニア3~4人+デザイナー0~1人という感じです。 テーマは「一日X回(なるべく多い回数)起動されるアプリ」ということで、各チームが基本自主的にアプリを制作し、 チームに割り振られるメンターの社員2人(総合職1名とエンジニア1名)のフィードバックを受けつつ開発を進めていく感じでした。

f:id:Hoo:20150922000623j:plain

総合職(ピクシブ用語では一般職)に対しては スライドの作成、プレゼンテーションの方法であるとか、広報企画などについて、的確なアドバイスをいただきました。 また、エンジニアに対しても実装の細かなところからUIデザインをどうすべきかといったことまで助言をいただけました。 そういったフィードバックや、チームで2週間、いい雰囲気、すなわちよりよいコミュニケーションを取りつつ 開発していくための空気、そういうものを作っていくための施策とか、そういったところにはとても力を入れているように見えました。

これだけだと通常の業務からは距離があるように見えますが、講義という形で事業内容や、pixivで使われている技術についての話などもあり、 社内の会議にも参加するなど、完全に業務と関わりがないというわけではありません。 あと業務の一貫としてpixiv Spotlightの記事を作成する、ということもやりました。

もっと具体的に

Androidアプリの開発をやりました。一言でいうと「コーデに困っている人がアドバイスを貰えるアプリ」です。 スクリーンショットとかは著作権的にチームのメンバーの許可やら何やらが要りそうな気がするので今はなしで

開発環境

基本持ち込みで貸出もあります。 MacBook (Air|Pro)率はやっぱり高かった。

開発の様子

Githubのprivate repositoryをもらってそこで開発。 Issueとかを追えるように総合職の人にもGithubは一応触ってもらっていました。 余談ですが、総合職の人がテストで立てた「生きる」というIssueがCloseされたときは何事かと思いました。

僕がやったのはサーバーサイドですが、仕事が少なかったので半分くらいはクライアント側(Androidアプリ)の開発もやっていました。 FuelPHPをゴリゴリ書きました。

コミット数はマージコミットを入れずに180回くらい、チームで書いた行数は自動生成されたものを含めて5000行程度でした。 サーバーサイドは実質400行程度しか書いていないので割愛。

結果

優勝ならず…に終わってしまいました。 ドッグフーディングではUIデザインなど、割りと好感触だったのですが、最終発表の後、 コーディネートを評価する側、評価される側の動機づけが根本的に弱いのでは といった意見をいただいたりしました。 実際の業務と同じ視点で、厳しい評価をいただけるというのもまた、このインターンの良い所だと思います。 僕としては学ぶところの多いインターンとなったし、興味深い人たちと交流することができ、 行ったかいがあったと思っています。

お世話になった方々、ありがとうございました。

f:id:Hoo:20150927121709j:plain 笑顔の絶えない、アットホームな開発環境になりました。(本当に)

余談

インターンをこれだけ取る理由

pixivの社員数は2015年5月1日時点で92名ですが、インターン参加人数は二十数名とだいぶ多いです。 経済的にも人員的にも結構な負担ではないかと思います。 これだけの人を取る理由を片桐社長にお伺いしたところ、優秀な人が多かったというのと、 間接的にしろpixivと関わるかも知れない人にpixivという会社でいい体験をしてもらいたかったから、という理由だとおっしゃっていました。

オフィスの雰囲気

pixivのオフィスの雰囲気はこんな感じです。

recruit.pixiv.net

こちらはひとつ前の古いオフィスの方ですが、雰囲気はほぼ変わらず。

blog.kushii.net

こういった遊び心満載のオフィスを覗くのははじめてでした。楽しく仕事ができる雰囲気でした。

フリードリンク

pixivのオフィス、なんと飲み物が無料です。 お茶や缶コーヒーとかが取り放題で、大変お世話になりました。 なんとそれだけではなく、みそ汁も飲み放題となっておりました。

みそ汁が飲み物の範疇に入るかは議論の余地があると思われますが、pixiv内ではみそ汁は飲み物となっているようです。

これがチームメンバーに大変好評で、毎日のKPT(反省会)に 必ずフリードリンクとみそ汁についての話題が出されていました。

HTML5 + CSSがチューリング完全であるという話

この前非情報系の友人と飲んでいて話題に出そうとして出せなかった話。

その友人は以前HTMLがプログラミング言語だとうっかり情報系の先輩の前で口にしてしまい、当然のごとくそれは間違っているとツッコミを受けたそうだ。

そこで「実はHTML(+CSS)はチューリング完全と言えなくもないからプログラミングはできるんだよ!」というこの前聞いた話を振ろうとしたものの、相手はチューリングテストチューリングマシンの違いも分かっていなかったので諦めたのだった。ウカツ!

チューリングテストチューリングマシン

f:id:Hoo:20140912163452j:plain

Ⓒ Duane Wessels 2012

どちらも計算機科学の発展に大きく寄与したアラン・チューリングによって考案された概念。 (でも中身は月とスッポンくらい違う)

チューリングテストとは

f:id:Hoo:20140912164542p:plain

チューリングテストはある機械が知性を持つかどうかを判定するためにチューリング先生が考えだしたテストのこと。 どういうテストをするかというと、判定者が人間とコンピュータを相手に(文字で)対話を行い、判定者が人間とコンピュータを明確に区別できなければそのコンピュータは知性を持つと判定する。

ただし、結局は人間の主観で判定するため、明確な合格というのは定義しづらい、というかできない。 最近"合格した"と主張するAIが出てきたらしい。

史上初のチューリングテスト合格スパコンが登場、コンピュータの「知性」を認定 - GIGAZINE

チューリングマシンとは

チューリングマシンとは計算機を数学の世界に持ち込むためにチューリング先生が考えだした、 ものすごーく単純な仮想機械のこと。(ただし、考案された1936年当時電子計算機なんてものは存在しなかった!)

チューリングマシンとは 【 Turing machine 】 - 意味/解説/説明/定義 : IT用語辞典

チューリングマシンはあらかじめ設定された幾つかの「状態」を持っており、その「状態」とヘッドから読み出したデータの組み合わせによって、「ヘッドをテープ上で一マス移動させる」「テープのヘッドのあるマスにデータを書き込む」「『状態』を変更する」のいずれかの動作を行う。その後、移動後のヘッド位置からデータを読み込み、そのデータと新しい「状態」の組み合わせに従って、次の動作を行う。

とても単純な原理で動作するが、一定の計算手順(アルゴリズム)に基づいて答えが出せるような問題はすべてチューリングマシンで 答えを求めることができる。(もちろんチューリングマシンで答えを求められないような問題はアルゴリズムに基づいてコンピュータで解くことはできない。)

そしてある計算のメカニズムがこのチューリングマシンと同等の計算能力を備えていることを、チューリング完全と呼ぶ。

HTML+CSSの計算能力について

と、ここまでが前座である。ここからが本題のはずだったが、巻いて説明しようと思う。

プログラミング言語はある意味でアルゴリズムを記述するための言語である。チューリング完全でないプログラミング言語処理系は 存在価値がない。(メモリとか現実的な制約は抜きにして)

では逆に、ある言語がアルゴリズムを記述できるならプログラミング言語と言えるだろうか? 実は世の中にはプログラミング言語と呼べないまででもチューリング完全になってしまったものがたくさんある。

本の虫: うっかりチューリング完全になっちゃったもの

百聞は一見にしかず。これ(Rule 110)を開いて一番上の行をどこかクリックし、 左上の指示にしたがってTabとSpaceをカチカチやってみよう。開くのが面倒な人には動画もある。


Eli Fox-Epstein's Rule 110 HTML & CSS3 Machine ...

ライフゲームを知っている人はそれっぽい動きと思ったかもしれない。

これはルール110と呼ばれるセル・オートマトンを完全にHTMLとCSSのみで記述したものである。 このルール110セル・オートマトンは実はチューリングマシンと同等の計算能力を備えていることが示されている。

これを書いた人は "This was the first proof ever that CSS is Turing-complete." と冗談めかして書いているが、実際にこれがチューリング完全であるかどうかは海外のフォーラムでも議論されている

落とし所がなくなってしまったが最後に、チューリングの伝記が映画になるそうである。 日本での公開は今年の年末になるらしいので、気になる方は見に行ってみてはいかがだろうか?

アラン・チューリングの伝記映画“The Imitation Game”公式トレーラー2種。追記。 新・豆酢館/ウェブリブログ

チューリング

チューリング

hubot-twitter-userstreamをリリースしました

先月の話になりますが、HubotからTwitterへ投稿するためのAdapter hubot-twitter-userstreamをnpmで公開しました。

Hubotとは

f:id:Hoo:20140808154918p:plain

Github社が作成したチャットボットです。CoffeeScriptで書かれており、Node.js上で動作します。 Hubotはチャットに接続、投稿するためのAdapter, メッセージやイベントにレスポンスを返すScriptなどから構成されており、 それらのモジュールを導入することで簡単に様々なチャットサービスで動作するBOTを作ることができます。

hubot-twitter-userstream で何ができるのか

そもそもHubotのTwitter用のAdapter(MathildeLemee/hubot-twitter · GitHub)はすでに存在していたのですが、実際BOTを作るにあたっていくつか 難点があり

  • タイムラインからツイートを取得できない

    Twitter上で動くBOTは普通タイムラインのツイートを取得して、ツイートによっては反応してリプを返すという挙動を期待すると思うのですが、 hubot-twirrerではstatuses/filterを用いて、自分の名前を検索してマッチしたツイートを受信するという ちょっとよくわからない挙動になっています。これだけでもリプライを送ったりするBOTを作るには致命的です。

  • フォロー・リムーブができない

  • ダイレクトメッセージが送れない

等々致命的な弱点があり、BOTを作る前に、Adapterを自分で作ってやろうと思い至った次第です。

hubot-twitter-userstreamでできること

  • ツイートの投稿、返信ができる
  • UserStreamを使ってタイムラインからツイートを取得できる
  • フォロー・リムーブができる
  • ダイレクトメッセージの送受信ができる
  • フォローされた、ふぁぼられた等のイベントが受信できる

できないこと

  • RT
  • 画像のアップロード
  • フォロー・フォロワー一覧の取得(例えばBOTを起動していない時にフォローしたユーザーをリフォローできない)

導入方法

Hubot自体の導入方法は hubot/docs at master · github/hubot · GitHubはじめてのHubot - Qiita を参照してください。

自分のBOTがあるディレクトリmyhubotは用意出来ましたか?出来ましたね!

導入はmyhubot/package.jsonを編集して"dependencies"に「"hubot-twitter-userstream": ""」をこんな感じで追加して

...
  "dependencies": {
    "hubot":         ">= 2.6.0 < 3.0.0",
    "hubot-scripts": ">= 2.5.0 < 3.0.0",
    "hubot-twitter-userstream": ""
  },
...

myhubotディレクトリ中で npm install を実行すれば myhubot/node_modules ディレクトリ中にインストールが行われます。

次に環境変数TwitterAPI keyをいくつか設定する必要があります。

$ export HUBOT_TWITTER_KEY="key"
$ export HUBOT_TWITTER_SECRET="secret"
$ export HUBOT_TWITTER_TOKEN="token"
$ export HUBOT_TWITTER_TOKEN_SECRET="secret"

それから、自分のスクリーンネーム(ここでは@hubottestとします)をBOTの名前に設定します。

$ export HUBOT_NAME="hubottest"

これで準備は完了です。

使い方

pingを返す

myhubotディレクトリ中で ./bin/hubot -a twitter-userstream と実行することでBOTが起動します。 BOTには初期状態でいくつかScriptが組み込まれているのでテストしてみましょう。

まずBOTのアカウントで自分のアカウントをフォローさせてから「@hubottest ping」というようにリプライを飛ばしてみましょう。 成功すれば、BOTが「PONG」とつぶやきます。

リフォローする

BOTをフォローしたユーザーをフォローするには、 以下のようなスクリプトを用意してscriptsディレクトリに入れて、BOTを再起動します。

# myrules.coffee
module.exports = (robot) ->
  robot.on 'followed', (event) ->
    robot.logger.info "followed #{event.user.name}!"
    robot.adapter.join event.user

rdiff-backupを使ってバックアップしてみた

rdiff-backupとは

rdiff-backupとはファイルやディレクトリのバックアップを取ることが出来るツールです。 rsync差分バックアップ機能をつけたもの、というイメージでだいたいあってます。

(内部的にはrsyncを使っているわけではなく、rsyncの差分ファイルを作成するのに使われるrdiffというプログラムを共通で用いているだけなので、細かい差はある。)

rdiff-backup は、ネットワーク対応のディレクトリバックアップツールです。ディレクトリの完全なコピーが保存されるとともに、特別なサブディレクトリに逆差分ファイルが保存され、過去に失われてしまったファイルを復元することが出来ます。すなわち、ミラーと差分バックアップのいいところ取りです。rdiff-backup は、サブディレクトリ、ハードリンク、デバイスファイル、パミッション、所有者のユーザー/グループID、ファイル変更時間、拡張属性、アクセスコントロールリスト、リソースフォークを保存します。

気まぐれサーバー - rdiff-backup - ローカル/リモートのミラーと差分バックアップ-rdiff-backup-気まぐれ Wiki http://web.archive.org/web/20100328234759/http://seki.jpn.org/modules/pukiwiki/index.php?rdiff-backup

機能

  • ネットワーク経由でのバックアップ

    rsyncと同様に、リモートシェル経由でのバックアップに対応しています。 その場合、サーバー・クライアント双方にrdiff-backupをインストールする必要があります。 rsyncと同様に、バックアップを置くターゲット側、バックアップをとるソース側のどちらからでもバックアップは行えます。

  • ミラーリング

    バックアップ先にはディレクトリの完全なコピーが作成されます。

  • 逆増分バックアップ

    差分を逆方向に、すなわち差分a,b,c,...を

    最新→(a)→一つ前→(b)→2つ前→(c)→3つ前...

    みたいにとっていき、保存するのは最新のファイル全体と差分のみにするという方法。 完全バックアップに比べ、使用するディスク容量、バックアップ時間等を抑えられます。

rsyncに比べると遅くなる、各種機能(例えばcopy-links,copy-unsafe-linksなど)が使えないなどのデメリットがあります。 また、増分バックアップはバックアップファイルのうち1つでも壊れるとすぐに過去のバックアップが読めなくなってしまいます。 増分の作成中やファイルの更新中にバックアップが中断した場合容易に過去のバックアップが消えうるため、容量に余裕がある場合には 数世代の完全バックアップ行うことを強く勧めておきます。

ディスクに余裕がないけど複数世代のデータのバックアップが欲しいとか、バックアップの頻度が多く増分バックアップが必要という人にはオススメ。

使い方

$ rdiff-backup dir1 dir2

を実行すると、dir1の内容がdir2にバックアップされます。

dir2にはdir1の直下にあるディレクトリ・ファイルがミラーリングされ、またrdiff-backup-dataというメタ情報を格納したディレクトリが作られる。 ここにはパーミッション、所有者のユーザー/グループIDなんかが入っています。

これらの情報をファイルとは別に管理するため、rsyncと違いバックアップにroot権限が要らないのは結構な利点。

実行結果

$ mkdir dir1 dir2
$ touch dir1/foo
$ tree .
.
|-- dir1
|   `-- foo
`-- dir2

2 directories, 1 file
$ rdiff-backup dir1 dir2
$ tree .
.
|-- dir1
|   `-- foo
`-- dir2
    |-- foo
    `-- rdiff-backup-data
        |-- access_control_lists.2014-06-30T13:37:23+09:00.snapshot
        |-- backup.log
        |-- chars_to_quote
        |-- current_mirror.2014-06-30T13:37:23+09:00.data
        |-- error_log.2014-06-30T13:37:23+09:00.data
        |-- extended_attributes.2014-06-30T13:37:23+09:00.snapshot
        |-- file_statistics.2014-06-30T13:37:23+09:00.data.gz
        |-- increments
        |-- mirror_metadata.2014-06-30T13:37:23+09:00.snapshot.gz
        `-- session_statistics.2014-06-30T13:37:23+09:00.data

4 directories, 11 files

以下のように指定すると、ネットワーク越しに同期ができます。

rdiff-backup dir1 user@system::/dir2

詳しい使い方を知りたければmanを参照するのが一番わかりやすい。 あまり日本語の情報量は多くはありませんでした。

rdiff-backup: Documentation

実際の運用

個人的に運用しているサーバーのバックアップとして導入しました。 そもそも以前はミラーリングだけしか行っておらず、バックアップとしては不十分な状態でした。

これを導入することで、増分バックアップとはいえ複数世代分のバックアップを残せるようになったのは大きいと思っいます。

バックアップはソース側となる公開サーバー上でcronを実行してターゲット側となるバックアップマシンに同期を行うようにしています。 これに関してはどちらから同期を行っても良かったのだけれど、root権限がないと読み出せないデータをバックアップしている以上、 公開サーバー上のSSHに(forced-commands-only,IP制限等はかけるとはいえ)rootで入れるようにするよりは、バックアップサーバー上の 一般ユーザーに入れるようにしたほうが良いと考えこのようにしました。

もし定石のようなものがあれば教えて下さい。

また、SSHのforced commandを使って次のように鍵の設定を行うことで、この鍵で接続した場合相手の入力に関わらずcommandが実行され、 rdiff-backup以外のプログラムを走らせること、rdiff-backupが/backup以外のディレクトリにアクセスすることを制限できます。

# authorized_keys
command="/usr/bin/rdiff-backup --server --restrict /backup"
,no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa (公開鍵)

参考

rdiff-backup: Main

気まぐれサーバー - rdiff-backup - ローカル/リモートのミラーと差分バックアップ-rdiff-backup-気まぐれ Wiki

rdiff-backup をもう少し使いこなす - いますぐ実践! Linuxシステム管理 / Vol.155

rdiff-backup の使い方 | サイト運営の私的メモ

P.S.

今のところ順調にrdiff-backupは動いているが、海外のフォーラム等ではデータが壊れた旨の報告を相当数見つけた。

データが壊れたらまたエントリにするかもしれない。

30分で試せる分散並列プログラミング Linda についてのあれやこれや

はてなブックマーク - wise9 › 30分で試せる分散並列プログラミング Linda (PC遠隔操作編)
http://b.hatena.ne.jp/entry/wise9.jp/archives/8391
での私のブックマークコメント「記事書いてる人の知識の無さがすごく残念」に対して
>id:shokai id:Hoo 十分足りてると思いますが・・
とあったので少しばかり反論を

>サーバーもクライアントもブラウザーで動かす
サーバー側もブラウザ上で動いているかのように読み取れますが、linda-baseは別にブラウザ上で動いているわけではありません。

したがって
クライアント側からサーバーを抽象化したモデル的に扱うことができる
という方が正しいのではないでしょうか。

>Lindaは並列プログラミング言語といいながら、普通の直列(?)プログラミング言語から簡単に使えてしまうことだ。
Lindaは言語ではなく、並列処理を行うための実装モデルのようなものにすぎないため、JavaScriptから扱えるよう実装されていれば使えるのは当たり前です。

>そういう意味ではLindaは非常にシンプルかつ強力だが、悪意ある情報や偽情報からシステムを保護するのが難しいという弱点がある。
私がWikipedia等を読んだ限りではLindaはただのモデルであり、並列プロセス間の通信をどうするかはすべて実装に任されています。
通信での脆弱性はアプリケーション側が対応すべきことだし、100歩譲ってlinda-baseの脆弱性であってもLindaの欠陥とは呼べないのではないかと。


以上の理由より、上記事ははじめてLindaに触れる人に対してあらぬ誤解を招く記事となっているのではという感想を抱き、以上のコメントを残しました。
とっかかり、導入方法に関してはわかりやすい記事であるだけに、正確さに書ける部分が残念だと思ったのです。決して執筆者の誹謗中傷を目的としたものではありません。

あと、CSRFをPC遠隔操作と呼んでいる、直列プログラミング言語等、
香ばしい単語に過剰に反応してしまったところはあり、そこは反省しています。

参考:http://ja.wikipedia.org/wiki/Linda
http://en.wikipedia.org/wiki/Linda_(coordination_language)

PHPのcall by reference

今日は外が嵐だったので半日Wikitccのソースを眺めていました。
あ、WikitccとはPHPで書かれた(遠い先輩の)お手製のWikiエンジンです。

PHPを触るのは(ほぼ)初めてだったのですが、意外とすんなり読めました。
公式リファレンスも充実してますね。カレー味だから許せるよねといった感じです。

で、PHPのバージョンアップで挙動がおかしくなっていた部分を直しました。

//generic.php, l135
return array_pop(explode(".", $path));

このコードがPHP5では "Strict Standards: Only variables should be passed by reference" と何やらワーニングのようなものを吐いていました。
array_popの仮引数が参照渡しを要求するにも関わらず値を直接渡しているのが原因です。
これを解決するには

$tmp=explode(".", $file);
return array_pop($tmp);

と一旦変数にいれてやるしかないらしいです。

この辺り、C++と似た気持ち悪さを感じます。

string huga(){
        return "hoge";
}
string hoge(string &a){
        return a;
}
hoge(huga()); //<-Error

ただ参照型と値が混在している、というだけなら他の言語、例えばC#Javaだってそうなのですが、この2つの言語では渡すのは""で統一されています。(参照型も参照の"値"渡し)

それに比べてPHP,C++では参照呼びと値呼びどちらもある、すなわち
関数を呼び出してる段階では引数がどちらで渡されるのかさっぱりわからない!
から混乱してしまうのでしょう。

そういえば今思い出したのだけれど、このプログラムの構造、zickさんが随分前に書いてたこれ
http://blog.bugyo.tk/lyrical/archives/861
と同じでした。
PHPはStrict Standards吐くだけで動くことは動くので、PHPはcall by referenceと呼べる かもしれない。

あなたがカッコの多いプログラミング言語でプログラムすべきでない8つの理由

先日Twitter上でこのような画像を目撃してしまいました。
f:id:Hoo:20130401175226j:plain

新年度にあたってプログラミングを始める方々、特に新入生、新社会人におかれましてはこのような宗教勧誘ビラに騙されず、幸せなプログラミングライフを送っていただきたいと切に願い、この記事を書こうと思い立った所存です。

続きを読む