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

LifeTimeException@hrk623

This is my breakpoints and stack-trace for my life

恋人と喧嘩ばかりの人が試してみればいいと思う事

f:id:hrk623:20120727225507j:plain

 

 恋愛関連の記事としては第二弾になるのかな?恋愛とか、人と付き合ってると喧嘩ってするよね。イライラするしムラムラする。でも、喧嘩なんかしたくない!って思ってる人がほとんどだと思います。って事で、今回はしたくない喧嘩ばかりしてる人に試してもらいたい事を提案してみます。ちょっと思い出してみてください。最近、相手に腹がたったのってどんな時でしたか?察するに「なんでそんな事するの?」や「なんで分かってくれないの?」など、自分の思い通りにならなかった時ではないでしょうか?メールしたのに返してくれない!イライラしますね。好きって言って欲しいのに言ってくれない!イライラしますね。彼女が毎晩一緒に寝ようとする!ムラムラしますね。襲いかかったら拒否される!イライラしますね。どうすればいいのでしょうか。解決法はズバリ、『相手に期待しない』事です。

 

よく聞く話を例として出してみます。

 一緒に食事に出かけた際、彼氏が奢るのが当たり前だと考える女性がいるとします。そうとは知らず、その女性を食事に誘った彼氏が割り勘をもちかけます。すると、女性としてはやはり釈然としない物がありモヤモヤが残ります。ひどい時は喧嘩にまで進展してしまいます。さて、この女性と男性の間には明らかに価値観のズレがあります。この場合、恋愛観念における常識のズレとも言えます。ではなぜ、二人の間にある常識のズレが喧嘩にまで発展してしまうのでしょうか?

 

原因はあなたの期待にあります。

 ここが重要です。あなたの恋愛の常識はどこから得た知識か考えてみてください。漫画、映画、ドラマ、アニメ、小説、恋愛マニュアル、知り合いや周りの友達の経験談、自身の妄想などだと思います。本来、学校教育では学べない物ですし、みんなが等しく共通意識を思っているはずがないので差がでるのは当然です。そして、それぞれが上で挙げたような物から自分がときめいたセリフや気に入ったやり取りを覚え憧れてきたのです。さらにそれを色々な物から繰り返し取り込んでいるうちに、それが自分の中の常識になったのです。ここまでくるとそれは常識と言うよりも、理想です。上の例で出した女性は、自分の理想を彼氏に期待したのに、こっぴどく裏切られたのでイライラする結果となったわけですね。でもこれ、言い換えると、勝手に期待して勝手に裏切られて勝手に怒ってるんですよ。一人芝居もいいとこですよね。期待する→裏切られる→腹が立つ→喧嘩という流れが見て取れると思います。

 

期待するのをやめよう。

 原因が分かれば簡単です。相手に期待するのをやめれば喧嘩にならないのです。仕事が終わって帰ったら奥さんが風呂もご飯の準備も掃除もせずにゴロゴロしてるとイラッとするのに(古い?)、飼い猫には腹が立たないのも猫にそんな期待はしていないからではないでしょうか?・・・とは言うものの、恋人なんです。付き合ってるんですよ?期待したいですよね?僕も個人的には、付き合ってる以上相手に期待する権利はあると思うし、精一杯相手の期待に答えようとするのが恋人の義務だと思います。という事で、この『期待しない方法』はイラッとした時だけ使うようにするのがいいと思います。期待する→裏切られる→腹が立つ→「いやいや、自分が勝手に期待したことだし」→喧嘩回避といった具合に上手く挟んでいきましょう。これによって、自分の気も楽になるし、喧嘩によって相手の価値観を否定してしまう事もなくなります。また、逆に期待通りの事をしてくれた時は感謝の気持ちを忘れずに。

 

 いかがでしょうか。恋愛だけでなく、人付き合いには我慢がつきものです。でも、我慢ばかりでは大変なので、たまには違う視点をいれてみると少し楽になるかも知れませんよ。って事で今回はおしまい!

 

※画像はhttp://www.ashinari.com/2012/03/04-358628.phpから拝借

暇だったのでソニーの例題やってみた。

f:id:hrk623:20111229050516j:plain
http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/go_for_it.htmlより。

public class Cube {
  private class Coordinate{
    private int x, y, z;
    public Coordinate(int x, int y, int z){
      this.x = x;
      this.y = y;
      this.z = z;
    }
    public int x() { return x; }
    public int y() { return y; }
    public int z() { return z; }
  } // private class Coordinate
	
  private Coordinate leftBottomFront, rightTopBack;

  public Cube(int x, int y, int z, int width, int height, int depth){
    leftBottomFront = new Coordinate(x, y, z);
    rightTopBack = new Coordinate(x+width, y+height, z+depth);
  }
		
  public boolean intersects(Cube other){
    if(this.left() > other.right() || other.left() > this.right()
      || this.bottom() > other.top() || other.bottom() > this.top())
      || this.front() > other.back() || other.front() > this.back())
        return false;
    return true;
  }

  public int left(){ return this.leftBottomFront.x(); }
  public int right(){ return this.rightTopBack.x(); }
  public int top(){ return this.rightTopBack.y(); }
  public int bottom(){ return this.leftBottomFront.y(); }
  public int front(){ return this.leftBottomFront.z(); }
  public int back(){ return this.rightTopBack.z(); }
} // public class Cube

Coordinateクラス

  • private classとして3次元のCoordinateを定義。
  • とりあえず今はいらないのでセッターは作らず、ゲッターのみを設置。
  • わざわざCoordinateを作るのはInformation hidingとFlexibilityのため。
  • 後々Triangleとか作るなら、そのまま外に出してreuse出来るしね。
  • ゲッターは慣例に従ってgetXのようにgetから始めるべきだが、ここでは可読性を重視。

Cubeクラス

  • なんでCubeかって?それしか思いつかなかった。
  • Cubeは2つの座標から定義される。
    • 手前左下の座標
    • 奥右上の座標

intersectメソッド

  • 重なり判定用メソッド
  • 重なればtrueを返すのではなく、重ならなければfalseを返す方がスッキリだね。


テストケース・・・だと・・・?

hatenablog.comドメインで作ってみた

これで、公開ブログになるのか!

しかし、ブログが乱立するな。どう住み分けるべきか・・・。

元のブログから記事のインポートは出来ない様なので、完全なお引越しはまだ先かな。

でもHTML編集が出来るのは面白い。

ボストン・キャリア・フォーラムで就活してきました。

 2011年度ボストン・キャリア・フォーラムに参加してきましたので、その経緯やら結果もろもろを大まかに報告しておこうと思います。面接における問答も言い回しを変えたり省略しながら紹介しています。うろ覚えな部分もありますがだいたい合ってると思います。企業名は伏せています。詮索は無しの方向で。

ボストン・キャリア・フォーラムって何?

 年に一度、秋にアメリカのボストンで3日間開催されるキャリア・フォーラムです。日本の大手企業や海外進出を狙うベンチャー企業が集まり、ブースを構えセミナーや面接を行います。対象は、日本語+何かを話せるバイリンガルな学生で、北アメリカ全土から、ヨーロッパから、日本から就活生が集まり、早ければ1日や2日で採用が決まります。日本で就職したいけど、日本で就職活動が出来ない留学生にとっては唯一の就活手段です。

事前エントリー

 BCFのウェブサイトを通してエントリーシートを提出しておけば、フォーラム開催前に面接のアポを取ることも可能ですので一応やっときました。僕は以下のIT系の3社に応募

  • 大手S
  • 大手NT
  • ベンチャーC

 ベンチャーCは、すぐに技術部長さんとのスカイプ面接をさせて頂く事になりました。自室でスーツを来てMacの前に座るという異様な光景に対して、面接官の方はパーカーを着ていて拍子抜け。楽しく談笑した後、スタバでキャラメル・マキアートを飲んでいると、メールで「Bostonでも面接しましょう」とのお誘いをうけ、よろしくお願いしますと返信。その他の企業からは不採用の通知を頂きました。

 正直、テストも始まっていたのでエントリーシートを書いてる時間が惜しかったです。就活失敗より成績低迷の方が今後の人生に大きな影響を与えるという海外学生の苦悩を汲んでほしい(切実)。そんな中、エントリーシートの提出を求めないベンチャーCさんが神だという事は言わずもなが。ちなみに、いくつかの大手企業はエントリーシートに加えてWebテストもあるという鬼畜っぷり。

11月11日(金)
  • 10時
    • 会場到着
    • とりあえず履歴書の印刷
    • パンフレット漁る
    • ダメ元で大手SにWalkinで履歴書提出→不採用
    • 大手Pに履歴書提出→通過
  • 2時半
    • ベンチャーC面接(20分)→惨敗
  • 3時半
    • たまたま隣にあった大手NにWalkinで履歴書提出しようと思ったら説明会に巻き込まれ、そのまま面接(20分)→通過
  • 6時
    • 閉館、一緒に来たメンバーでクラムチャウダーを食べに夜のボストンへ。

とりあえず、ベンチャーと大手の違いをハッキリと感じた1日目でした。

ベンチャーC

 面接して下さった方はやはりパーカーでしたw 面接での問答は、

  • 技術面で何が出来る?
    • 働いてみて、環境を把握しない内は分かりません。
  • 我が社にどう貢献出来る?
    • 同上。
  • 何をしたい?
    • 出来る事が分からないので何とも。

と、散々な結果。やはり、即戦力を求めているようです。しかし、その職場環境も知らないまま「〇〇が出来ます!」と言うのはあまりにも無責任に感じてしまい、正直に答えるしかありませんでした。自分が大学で得たスキルが、そこでどこまで通用するのかを自信を持って言うには経験が足りませんでした。言うまでもなく、不通知をもって不採用頂きました。

大手N

 対応してくれた方がものすごく親切で、企業研究もしていなかった僕に一から説明してくれました。後で調べると、日本のIT関係の人なら知らない人はいない程大手という事が発覚。問答の流れは、

  • 自己紹介して下さい
    • 名前、大学名、専攻、ボランティア活動とか言ってみる。
  • 専攻(BCS/SE)について詳しく
    • CSは数学
    • SEは哲学。
  • なぜ日本に戻るの?
    • 自国を知らない人間が海外で活躍できるはず無い(キリ
  • 得意な言語は?
  • コード10000行くらいは書いた?
    • その何十倍は書いてます。
  • 他にはどんな企業受けてる? 
    • IT系の大手とベンチャー
  • ベンチャーと大手の両方から採用されたらどうする? 
    • 決定打を見つけるまで調べる

 こちらも回答は特に用意していなかったので、その場で思った事を正直に答えています。ベンチャーと大手で迷っている僕に、面接官の方がアドバイスをくれました。「直感を信じて飛び込め」と。確かにそれも必要ですね。面接でアドバイスを頂いたのは初めてでした。


11月12日(土)
  • 11時
    • 会場到着
  • 11時55分 
  • 12時半 
    • 大手N二次面接→通過
  • 1時45分 
    • ベンチャーD面接→辞退
  • 3時半 
    • 大手N三次面接→採用
  • 6時半 
    • Westin HotelのVIPルームにて、大手Nの懇親会
    • 二次会でオイスター食べ放題

大手P

 順番待ちの席でエントリーシートに記入をお願いされました。結局書き終わらずに面接開始。問答(10分)

  • 大手Nと同じ様な感じ+
  • TOEIC何点?
    • 受けた事ありません。
  • 学業以外で頑張ってることは?
    • クラブ活動
    • ボランティアなどなど

面接官の方がひどくお疲れのご様子で、大変簡素な内容のお話でした。ちょっと書いたエントリーシートには目もくれず、発言に対する反応も薄く、少し居づらい雰囲気さえ醸し出していました。第一印象としては「あ、この人と働きたくない・・・。」それが伝わったのか、不通知をもって不採用を頂きました。

ベンチャーD

 珍しく女性の面接官。問答(10分)

  • 軽くひと通りの談笑を終えてから今エンジニアの面接官がいないので後日連絡します。
    • うぉぉぉぉぉおい!。

 後日、採用担当の方からご連絡を頂きましたが、諸事情により辞退させて頂きました。

大手N(2回目)

 1回目とは別の面接官の方でした。この面接が一番印象に残りました。問答(30分)

  • 自己紹介
    • いつも通り
  • どんな仕事がしたい?
    • 人の役に立つ仕事
    • 大学で学んだことを活かせる仕事
  • 仕事が人の役に立つのは当たり前でしょ?
    • 日本ではそうかも知れませんが、海外で人を不幸にする仕事はいくらでも見てきました。
  • なんでカナダに行ったの?
    • 留学の経緯を説明
  • 人生で挫折した事は?
    • 祖父にパソコンの使い方を教えられなかった事
  • 勉強するモチベーションは?
    • 将来の自分への投資
  • 将来的に海外に行きたいみたいだけど、いつそんなプロジェクトが立つか分からないよ?
    • しばらくは日本にいたい
    • もしタイミングが合えば海外進出のお手伝いがしたい。
  • もしかしたら一生そんなプロジェクトは無いかも
    • タイミングが合わなければ会社を辞めるかも。

 仕事が役に立つのが当たり前と言われたのは衝撃的でした。ただこの発言は、この面接官の方が詐欺などの存在を身近に感じていない事から出たのではなく、仕事は人を幸せにするためにするんだと心から信じている事からなのかもしれないと感じたのでした。また、将来的に海外に出たいというのは本心で、その妨げになるのであれば会社を辞めるかもしれないと言ったのも本心からです。「(この流れなら言える!)」と天の声に唆されて言ってみたのですが、面接官の方に「それはそうだろうね、愚問だった。すまんすまん。」と謝られてしまいました。

大手N(3回目)

 またまた別の面接官の方が登場。問答(30分)

  • 自己紹(ry
  • 部署によっては忙しくなるけど大丈夫?
    • 今の大学生活よりはましです。

 後は、ほぼ面接官の方の説明を聞いていました。とうか、8割方、相槌を打ちながら話を聞くだけでした。おそらく三次面接は意思確認なのかと。ちなみに、「採用された人の名前を5時までにブースの前に張り出します」と言われ、5時に行くと名前がない!!ダメだったのかーと立ち去ろうとした時、友達を発見し10分ほど立ち話をしていました。話し終わって、帰ろうかと思いながらもう一度確認すると名前が張り出されてました。

 結局、意外にも大手Nから採用を頂きました。エントリーシートもなく、企業研究もなく、履歴書は当日に提出しただけ。何の準備もしていなかったのに、ちょっと話をして自分の考えを正直に答えるだけで決まったのです。就職難と散々脅されていたので、本当に拍子抜けでした。
あと、面接中になんとなく合否は分かるようになりました。話してて楽しいと受かる。

まとめ

 僕の就職活動は、就活サイトに登録してから数えると2年、実質活動期間は1ヶ月、大手Nに関しては2日間と言う驚きの速さで幕を閉じました。考えてみると、僕は高校と大学は成績のみで入り、就職もこういう結果となり、「入る事」に関しては凄まじく楽に生きてきたように思います。(入ってから苦労していますが・・・)ですから、今になって少し「このままでいいのかな?」なんて迷っています。就職も大手Nに採用して頂きましたが、裏を返せば「ここしか受からなかったから、ここに行くしかない」とも言えるのです。聞いたり調べたりした限り、企業としてはとてもいい会社だと思います。将来性、給料、福利厚生などに魅力を感じている反面、バリバリのベンチャーにもまた憧れるわけです。面接官の方が仰った「直感を信じて飛び込め」という言葉を受け入れきれない自分がいるのです。これについては、もう少し考えてみたいと思っています。また、何かアドバイスがあればよろしくお願いします。

後日談

 大手NからWebテスト受けて下さいと言われ、結局受ける事になりましたw

最後に

 この記事は、決して就職活動やそれに尽力している方々を揶揄するものではありません。純粋に自身の記録と報告であり、またこれから就職活動する方の参考になればと思い公開させて頂きました。

「あ、この人プレゼン下手だな」って思う瞬間

 カナダに来てから、やたらプレゼンをしてきました。大小含めて、その数なんと100以上!そんな私が最近思った「プレゼンが下手な人の特徴」を(自戒も込めて)上げてみようと思います。内容とかの話ではなく、プレゼンのやり方のお話です。

1. 制限時間オーバー

 面白かろうがつまらなかろうが与えられた時間は出来るだけ守るようにしましょう。制限時間内に収まらないのは練習していないからではないしょうか。自分の考えやメッセージを伝えるための場に、準備もせずに立とうという姿勢は上手い下手以前の問題です。

2. 次なんだっけ?

 よく見るのが、次のスライドに切り替わると、スライドをその場で読んでから話し出すプレゼンターです。読んでる間の沈黙の2秒間が無駄で、これだけで聞き手の集中力が切れる事もあります。代わりに、説明が終わったスライドに聞き手が目を通す時間を入れると、余裕のある印象を与えます。沈黙の2秒間よりも、余韻の2秒間を心がけるともっと良くなるはずです。

 また、スライドは自分の発表内容を分かりやすくするための道具です。スライドがないとプレゼンが出来ないという状況にだけはならないようにしましょう。

3. スライドに書いてる事しか言わない

 極稀に見るのが、1段落を丸々スライドに書いているプレゼンターです。しかも、それをそのまま読むのですが、ハッキリ言って自分で読んだ方が早いです。出来るだけ箇条書きか、図や画像にしましょう。図や画像から得られる情報量の多さをしっかり意識しましょう。

 上でも触れましたが、スライドは補助的に使いましょう。プレゼンターの説明の後、聞き手が2秒でスライドに目を通せる、尚且つ内容を思い出せるくらいがちょうどいいです。

4. 笑いどころがない

 どんなにフォーマルなプレゼンテーションでもユーモアは必要です。人間の集中力を過大評価せずに、意図的に聞き手が頭を休められる時間を作りましょう。1時間に一回で10分の休憩を入れるより、5分に5秒程度の笑いをとれればいいと思います。練習の際、笑いが静まるまでの時間も考えるようにしましょう。

最後に

 大きく分けてこんなところでしょうか。プレゼンテーションは何かを教えたり伝えたりする行為です。「聞き手が聞いてくれない」や「聞き手が集中していない」のは、プレゼンターの責任だと思います。

 また、練習しなくても登壇出来る事はカッコいい事でも勇気のある事でもありません。聞き手の時間を無駄にするだけです。しっかり準備と練習をして、伝えたい事を伝えられるプレゼンターになりましょう!

インターン生に、はてなはすごいと思わせたはてなの何か。

 以前報告したとおり、株式会社はてなの『はてなエンジニアインターン2011』に参加してきました。はてなインターンは8月の中旬から9月の初めまでの約3週間のプログラムでした。その中で僕自身多くの事を経験し、また学ぶ事が出来ました。これは、いわゆる「お決まりの言葉」ではなく、本当に実感している事です。

 今回はそのインターンのレポートを書かせて頂くのですが、僕はもともとはてなの主たるサービスであるWebアプリケーションについての深い知識と経験を有していませんでした。そんな僕が技術的な部分の話を詳しくしてもつまらないので、代わりにインターンを通して技術面以外で深く印象に残った、でもあまりに表に出ていない様な事を幾つか綴ってみたいと思います。

はてな社員は弱音を吐かない

 インターンが始まって僕が特に気になったのが、オフィスのどこからも「めんどくさい」「やりたくない」「そんなの無理」などの後ろ向きな言葉が全く聞こえてこなかった事です。どんなにポジティブな人でも、疲れてポロッと言ってしまいそうな事も全然聞こえてこないのです。これは、はてな社員の方々の日頃のコミュニケーションに起因するものだと思います。僕がはてなにいたのは、ほんの3週間でしたがその一片を見せて頂きました。はてなには、団体意識を高めるコミュニケーション個人意識を高めるコミュニケーションが混在し、それらがバランスよく作用しあって社員の方々のモチベーションに繋がってるようでした。

団体意識を高めるはてなのコミュニケーション

 サービスの開発は基本的にはチームで行いますので、チームワークは大切です。チームワークとは各メンバーがチームに所属しているという事を自覚し、チームの状況をきちんと把握する事や、必要に応じて意見・妥協する事だと思います。

 まず、はてなの社員の方々、バイトの方々、インターン生は皆同じ時間に同じ物を食べます。食べながら、毎日違った人と違った話をします。僕自身、インターン生同士はもちろんの事、近藤社長や普段は話せないディレクターの方々と直接お話させて頂く機会もありました。同じ釜の飯を食った仲という表現がありますが、とても日本的な交流でほのぼのした空間がそこにあり、それは職種を問わず誰とでも意見交換を出来る場でした。

 他にも、はてなの社内には拍手が伝染病の様に広がる現象があります。オフィスのどこかで拍手が起こると5秒後にはオフィス全体が拍手喝采しています。おそらく、遠くにいる人は自分が誰に拍手をしているのかも分からないのでしょうが、されてる方は嬉しくなるものです。製品完成やリリースの喜びを社員全員で分かちあい、社員一丸となって全てのサービスを競いながらも応援し合う姿を見せつけられました。

 もう一つ驚いたのが、エンジニアが会社の儲けについて話していた事です。「収入が〇〇で利益が××どうたらこうたら。」これは、社内で必要な情報がきちんと交換されている証拠だと感じました。僕は、エンジニアが会社の経営状態や置かれている状況を把握している事は、とても大事だと思っています。それによって技術面の的確なアドバイスも出来ますし、数字として評価が見えるのはプラスになります。

 はてなでは、社員の方それぞれが、自身が開発チームに所属し、また会社という大きな一つのチームにもいる事をしっかりと認識しているようでした。

個人意識を高めるはてなのコミュニケーション

 僕が思う個人意識とは、自分がチームの一員である事の認識です。団体意思を尊重しつつ、自分で考え行動する力です。もっというと、自分を認め他人を認める事であり、簡単にいうと自信です。いわゆる自己啓発なのですが、はてなのやり方は面白い物でした。

 はてなには、毎朝社員が集まって報告し合う朝会なるものがあり、一通り報告が終わったら誰か一人が前で話す場があるそうです。お題は何でもよく、毎回面白い話が聞けるそうです。僕はよく知らない人に指示・説教されるより、よく知ってる人にされた方が信用できます。ですから、こういう風に個人が自己主張し、周りがその人の事を知る機会があるのはやはりプラスになる様です。

 また、はてなに来た時に繰り返し言われたのがこれです。「分からない事は聞いてください。一人で考えてる時間は無駄なので、ちゃんと聞いてください。」Webアプリケーション開発の知識が壊滅的だった僕は何をするにもかなり苦労しました。分からない事しかなかったのです。ですから、呆れられるのを覚悟で質問し続けるしかありませんでした。しかし、誰一人ため息一つつく事無く教えて下さいました。僕が技術的にも精神的にも、これにとても助けられたのは言うまでもありません。

 このような事が、個人がチーム内で自身の居場所を確立する事に繋がっているのだと感じました。はてなの社員方々は、ただ会社の歯車になるのではなく、それぞれが色を持ち輝いて見えました。

社長の想い

 もう一つ、忘れたくないと思った事があります。インターンが始まって2週間がたった日の夜、はてなのディレクターの方々と交流する場を頂きました。僕は近藤社長とお話させて頂いたのですが、その時にある疑問をぶつけてみました。


 インターンでお金を貰える仕組みが分からない。三週間もオフィスに居座って社員の方々の時間と労力も奪ってしまっているのに、その上給料まで出してもらえるのはなぜか。

と言ったふざけた内容だったのですが、その疑問に近藤社長は答えてくれました。


 確かに働いた事をいい経験として、それだけを持って帰ってもらう事も出来る。でも、せっかくの休みを3週間も使って来てもらうんだから出来るだけ多くの物を得て欲しい。お金を与えて優秀な人材を囲っていると思われる事もあるかもしれないが、給料を出すことで「働く」ということをもっとよく理解できると思う。それに、今回インターン生がこなした講義の内容を今度社員でもやってみるつもりだ。これは少なからず僕達もインターン生に来てもらう事で学んでいる事があるから。

 残念ながらメモ帳を持ち合わせていなかった上、お酒も入っていたので僕の勝手な解釈が多分に入っているかと思います。しかし、その言葉に胸を打たれた事はハッキリと覚えています。はてなの皆さんの中で、インターン生を受け入れる事は社内に新しい風を取り入れる感覚に近いのではないかと感じました。まだ、技術的にも人間的にも未発達は僕達をオフィスに迎え入れる事によって、新しい視点や考え、文化を取り入れようとしているようでした。こう考えると、僕のようなインターン生でも与えてもらうばかりではなく、何かを残せるのではないかと期待してしまいます。それはとても嬉しい事だと感じたのでした。

 この講義内容というのはサービス企画の講義で「10分間のブレインストームで出てきたアイデアを形にする」というものです。書きだして発表し描いて議論する、一見めんどくさい内容です。しかし、実際にその講義内容の一部を、後日社員の方々もされたそうです。それ聞いて、はてなのフットワークの軽さと新しい物を取り入れる勇気を改めて感じさせられました。

見えないものを意識する

 僕は、はてながすごい組織だと思えるのは「見えない物もちゃんと意識する」というスタイルだからだと思います。直接効率に結びつかない物が、間接的に効率に結びつく事はよくあります。例えば、感情です。仕事なんだから割り切ろうとしても、落ち込んでいるときは作業効率が落ち、嫌いな人とは意思疎通が難しいものです。上で書いてきたことは全てそこに集約します。

 コミュニケーションもそうです。コミュニケーションをとれというのは簡単ですが、実際にとろうとすると意外に難しいのです。だから、一見時間のムダに見えるような事をしてもコミュニケーションや自己表現の場を提供しています。それが結果として、社内の雰囲気に何らかの影響を与えているのだと思います。

 オフィスのお菓子や飲み物が飲み放題食べ放題な事にも、座敷でくつろげる事にも、ご飯が美味しい事にも、どれをとっても同じ事が言えると思います。はてなは、社員にとって居心地のいいオフィス作りなどの手間や時間、お金もかかる事に多く取り組んでいる会社です。それらは直接会社の業績や収入アップに繋がるものではないですが、全て間接的に作用して好循環しているんだと思いました。

まとめ

 レポートとして、報告したい事はたくさんあります。僕自身が自術者の卵として学んだ専門知識や技能は数えきれません。はてなのインターンシップとは3週間という限られた時間で発見と経験が押し寄せてくる、そういう場所です。もしこれを読んでいるあなたがこの先、はてなのインターンシップに参加する事があれば、オフィスを見渡して小さな事にも目を向けてみてください。想像以上の事が学べると思います。

最後に

 なんだか、ものすごく長くなってしまった事、また上から目線になってしまった事をお詫びすると共に、ここまで読んでくださった皆様、ありがとうございました。書き終わってから、僕自身「なんだか宗教じみた褒め方だなぁ」とか思ってしまいました。ですが、僕の率直なインターンの感想です。技術面で学んだ事はほんとに多くありましたが、それ以外にも学べる事がたくさんあった事が伝われば幸いです。
 また、個人的にも感謝しお礼をしたい方が大勢いますが、今回の記事では省かせて頂きました。メンターの方々、ディレクターの方々、インターン生の皆さん、その他にも多くの方に迷惑をお掛けし続け、お世話になり続けました。本当に有難うございました。

クイックセレクト(Quick Select)

 今回は選択アルゴリズムの紹介です。
これは、配列からk番目に小さい数を線形時間で
探しだすクイックセレクト(Quick Select)という
クイックソートの派生アルゴリズムです。

問題

 ソートされていないa1からanまでの数字がn個あり、
その中からk番目に小さい数字を探せ。

 例:
サイズが9の配列、[2, 5, 3, 7, 1, 8, 6, 0, 4]において、
3番目に小さい数は2です。

解1:ソートする。

 ソートしてk番目の数字を取る方法です。
ソートにθ(nlogn)と見つけるのにθ(n)なので、T(n) ∈ θ(nlogn)

解2:選択ソート的解

 リストから一番小さい数字を見つけ、取り出します。
これをk回繰り返します。
リストから最小値を見つけるのにO(n)なので
T(n) ∈ O(kn)です。

解3:ヒープソートの利用

 ヒープソートの構成にO(n)、取り出しにO(logn)なので
T(n) ∈ O(n+klogn)です。

解4:クイックセレクト(Quick Select)

 本題です。クイックソートのアルゴリズムを少し変えた解で
平均ケースでT(n) ∈ O(n)を実現します。

 ランダム、または何らかの法則でピボットを選び、
クイックソートと同じように再帰しソート処理を行います。
そして、ピボットより小さい数値のリストのサイズが
k-1であればピボットを返します。

擬似コード:

QuickSelect({a1, ..., an}, k)
 if n = 1 then return a1
 pick pivot x ∈ {a1, ..., an} at random
 L ← {ai : ai < x}
 R ← {ai : ai > x}
 l ← |L|
 if k = l+1 then return x
 else if k ≦ l then return QuickSelect(L, k)
 else return QuickSelect(R, k-l-1)

 左に再帰する際のサイズはl、右にはn-lとなります。
しかも、今回はどちらか一方にしか再帰しないので、
それぞれの再帰処理でT(max {l, n-l})として考えれば
上界が分かります。
最悪ケースは、l = 1 または l = nの時で

T(n) = T(n - 1) + θ(n) ∈ O(n^2)

理想は、毎回l =n/2をとる事で

T(n) = T(n/2) +θ(n) ∈ θ(n)

 つまり、クイック選択で理想値に近づくには
「良いピボットを選ぶ」事が必要不可欠です。

良いピボット

 では、良いピボットとは何か?と言うところから。
もちろん、n/2になるような中央値が最適です。
しかし、k個目に小さい数字を探すアルゴリズムを作るのに
n/2個目に小さい数字を探すアルゴリズムを使うなんて何だか変ですよね。
ここは少し、範囲を広めます。

「n/4 < l < 3n/4なるようなピボットxは良いピボットである」といいます。
なぜでしょうか。

確率Pr(n/4 < l < 3n/4) = 1/2で、
max{l, n-l} ≦ 3n/4ですから、
良いピボットを得るための必要ピボット取得回数の期待値は2となります。
これにより、
T(n) ≦ T(3n/4) +2θ(n)となり
T(n) = T(3n/4) +θ(n) ∈ θ(n)と言えます。

つまり、xが良いピボットであれば、期待ケースが Θ(n)となるのです。

では、そのようなピボットをどうやって見つけるのかです。
これには中央値の中央値(Median of Medians)と言う方法を使います。

中央値の中央値(Median of Medians)

問題:

 クイック選択のアルゴリズムにおいて、
n/4 < l < 3n/4になるようなピボットをO(n)で見つけろ。

 要は正確でなくてもいいから、大体の中央値を見つけるアルゴリズムです。
以下は、中央値の中央値を組み込んだクイックセレクトです。


QuickSelect({a1, ..., an}, k)
 if n = 1 then return a1

 // ここから中央値の中央値
 split {a1, ..., an} into groups G1, ..., Gn/5 each with 5 numbers
 for i ← 1 to n/5 do
  xi ← median of Gi // θ(1) since always 5 numbers or less
 x ← QuickSelect({x1, ..., xn/5}, n/10)
 // ここまで中央値の中央値

 L ← {ai : ai < x}
 R ← {ai : ai > x}
 l ← |L|
 if k = l +1 then return x
 else if k ≦ l then return QuickSelect(L, k)
 else return QuickSelect(R, k-l-1)

 ピボットの取り方だけが変わって、それ以外は同じですね。

では、なぜ中央値の中央値法は正しいのでしょうか。

 まずは一つ例を見てみます。
{7, 5, -3, 2, 1, 0, 4, 15, 25, 99, 3, -10, -1, 8, 9}で試します。
数字は15個あり、中央値の中央値法で選んだピボットが
(15)/4 < l < 3(15)/4の範囲に入るかどうか見てみましょう。

 まず、それぞれが5つの数字を持つようなグループに区切ります。
   G1 = {7, 5, -3, 2, 1}
   G2 = {0, 4, 15, 25, 99}
   G3 = {3, -10, -1, 8, 9}

 つぎに、それぞれの中央値を取ります。
   x1 = 2
   x2 = 15
   x3 = 3

 ここで一旦QuickSelectに再帰され、
中央値の中の中央値を返してきます。
   x = QuickSelect({2, 15, 3}, 1) = 3

 これで中央値の中央値は3となりました。
3をピボットとした場合、l = 6となり、
(15)/4 < 6 < 3(15)/4にちゃんと収まりましたね。

軽く証明:

 中央値の中央値で得られたピボットxを使うと
必ずn/4 < l < 3n/4になる事の証明です。

 まず、ピボットxは各グループG1,..., Gn/10
中央値の集合{x1, ..., xn/5}の中の
中央値をとってるわけですから、
約n/10個のxiはxより小さい事になります。
先程の例で言うと、x > x1です。

 さらに、それらの中央値より小さい数が、
それらのグループ内に2つある事になります。
x1 > 1, x1 > -3, x1 = 2, x1 < x
⇒ x > 1, x > -3, x > x1

 つまり、x ≧ 3n/10個の数となり、
これは l ≧ 3n/10となります。
同様に、x ≦ 3n/10個の数となり、
l < 7n/10です。

 よって、n/4 < 3n/10 <= l ≦ 7n/10 < 3n/4となり、
n/4 < l < 3n/4が証明されます。

クイック選択の解析

 さて、中央値の中央値の解説で
3n/10 <= l <= 7n/10が証明されたので、
max{l, n-l} <= 7n/10と言う事言えるようになりました。
なので、

   T(n) = T(n/5) + T(7n/10) + θ(n)

となります。
中央値を取るのに T(n/5)、
片方の再帰に T(7n/10) 、分割にθ(n)です。

それでは、今度はこの再帰式の解析です。
単純にみて、 T(n/5) + T(7n/10) = T(9n/10)なので、
小さくなっていってると見れます。なので、
とりあえずO(n)だろうと予想し置き換え法で計算します。

   T(n) = T(n/5) + T(7n/10) + an if n > 1
     or
   T(n) = 1 if n = 1

ですから、

T(n) ≦ cn for c > 0であることを証明します。
T(n) = T(n/5) + T(7n/10) + an
  ≦ c5/n + c7n/10 + an
⇒  n(c/5 + 7c/10 +a ) ≦ cnを証明します。
⇒  c/5 + 7c/10 + a ≦ c
⇒  c/10 ≧ a
⇒  c ≧ 10a
なので、c ≧ 10aである限りT(n) ∈ O(n)といえます。

お疲れ様でした。