Tumgik
takenos · 4 months
Text
2023年の振り返り
色々やることがあるので書かなくても良いかなと思ったけど、やっぱり書いておこうと思った。
人間の意識って不思議なもので、なにか自分の中で常識のアップデートが起きると、さも昔からそうだったかのように思い込んでしまう(GPT4から1年経ってないなんて信じられない)。良く言えばそれは過去に囚われず動けるということではあるけど、悪い面としては何も前進していないように感じたり、過度に固定的なものとして扱ってしまう。意識というメタソフトウェアに意図的に組み込まれた不具合。
そういった不具合を補正するために記録があり、記録を理解可能なものにするために、叙述がある。
まあこれはそんなに大したものではないけれど、なんとなくトピック別でまとめていく。
LLM : 大規模言語モデル
2023年の年明けは、何と言っても LLM だった。元々 GPT3の頃から一部の人が注目していたことを観測していたが、強化学習を施しチャットというUI を与えられてプロダクトとしても爆発的なヒットとなった ChatGPT のリリースが2022年11月、そして GPT4のリリースが2023年3月。
もともと機械学習周りは改めて勉強したいと思っていたので、Coursera の Machine Learning コースと Deep Learning コースを履修してみた。言語モデルだけでなく、CNN等画像を扱うための手法も学べた。その後、OpenAI の論文をいくつか読んだり。直接に手を動かして新しいモデルを開発するといったところまでは難しいが、重要なアイディアを理解することができ、収穫になった。
LLM のインパクトはここで書くまでもないだろう。自分でも API を使っていくつかプロトタイプを作ってみたのだが、汎用的なものは作っているうちに「あー、これ自分がやらなくてもプロバイダー側が作るやつだ」と気づいて作るのをやめた。具体的には、OpenAI の GPTs のようにプロンプトをカスタマイズして名前をつけて保存できるチャットボットや、GitHub Copilot in the CLI のようにコンソール上でやりたいことを自然言語で打つとサジェストしてくれる君などだ。どちらのプロダクトも今は便利に使っている。
逆に、Wantedly のドメイン(自然言語のアノテーション付き GraphQL API を最大限活用)を使って作ったプロトタイプは結構面白さを感じたし、デモの評判も良かった。自分のことを自分で説明するのはエネルギーが要る。聞かれて答える方が脳のニューラルネットワークを励起させることがたやすい。いきなり飛躍するが、日本で LLM を使って業務効率や生産効率を上げるのであれば、ドメインに浸潤するような、プロセス全体から変えていくようなソリューションの方が面白いかなと思っている。
ともあれ、LLM はこれからも確実に世界を変えていく。今後が楽しみなのは間違いない。
Developers Summit で話した
上記と並行して、2月には Developers Summit 2023 で Wantedly の人として話した(スライド)。ソフトウェアアーキテクチャを組織構造と一緒に価値に接続するというテーマ。
ソフトウェアアーキテクチャの問題は、いま目の前にあるチームの形との不一致がペインになって現場の声として現れることが多い。しかし経験上、そういうボトムアップな課題感を、そのままアーキテクチャに落とし込んで大きく変更する戦略は上手くいかないことが多い。
これはソフトウェア設計の概念を借りると依存関係の矢印が間違っている設計だと言える。営利企業である以上(あるいはサービスの価値を上げたい以上)、組織構造も “それ” に緩やかに依存して下支えするように設計されている。ソフトウェアアーキテクチャも“それ” に緩やかに依存するべきだ。しかし、目の前にある組織構造に依存してソフトウェアアーキテクチャを設計してしまう。そして組織の変化でアーキテクチャがまた適合しなくなる。
何を変数にして何を定数とするかを考えよう。
この辺りの話が 「Accelerate」 に加えて「チーム・トポロジー」が出たことでようやく共通の言葉で話せるようになったなと感じる。こういう Wantedly のシステムにおける学びを世の文脈の中に置くことは意味あることだと思ってお話させていただいた。
技術の進化
同じ時期、いまあるソフトウェアシステムを叙述によって理解可能にするという観点から、10年間の技術の進化(直接見たのは7年間だが)をまとめたのだが、これは学びがあった。
ある技術 A を導入していたから可能になった技術 B がある。ここまではある程度の人が認識できるのだが、それが A→B→Cのような多段になっていたり、複合的な要因だったりすると案外と認識できていない部分があったりする。あるいは認識できていても、技術を投資として見たときに、蓄積的な効果がどの程度あって、それに要するリードタイムがどのくらいなのか、といったこと。それを踏まえて考えられる戦略的なソフトウェアの技術投資とは、ということ。
この図はそういうことを考える良い機会になった。
Tumblr media
https://docs.wantedly.dev/introduction/technical-overview より
加えて言うと、この図には入らなかったけど明らかに重要な、並行して変化する外部構造が二つある。せっかくなので書いておく。
一つは会社に��ける事業とサービスの展開。・・・まあこれは結構自明ではあるのだが、あるサービスを展開する際に行ったある技術的なチャレンジが副産物を生み出した、といったことを陽に認識することができた。流れの早い IT スタートアップにおいて、技術の研究開発チームのようなものを独立して作るよりは基本的に走りながらやる方が上手くいく。ただしそのためのチャレンジマネジメントは必要で、これはテックリードの役割だと思う。
もう一つは会社の外のこと。こうやってタイムラインを見ると、明らかに2010年頃からのスマートフォンと社会的な普及が多くの影響を及ぼしている。Web アプリとユーザーインターフェイスおよびそのデプロイの仕方が分化し、同時にユーザーの期待値が変化し、それを解決するための技術が出てきて、オープンに使えるようになって、、、と言ったことをタイムラインと一緒に見ていくと面白い。マクロな構造が変わったとき、実は同じ問題意識を持っている人というのが同時多発的にいて、その中で技術が生まれて収斂していく。
昨今の生成 AI の盛り上がりで AI を動かす GPU を生産する NVIDIA の株が爆上がりしている。これなどは明確なハードウェアの生産量やコストの形を取るのでまだ一見分かりやすいが、オープンソースソフトウェアなどはもっと非金銭的な動機(たとえば鍵となる技術やビジョン)に導かれていることがむしろ普通で、実際に触ってみて中に入って理解する必要がある。そうやってドライバーを見極めつつ、自社の問題との一致を見出して、取り入れるタイミングを見計らう。取り入れたら、自社に適用するためのさまざまなプラクティスなど広義の意味での「技術」を組織の内部に蓄積していく。
こういったこともテックリードがいれば一定担保できるが、この通り様々な技術領域やレイヤーを超えて技術の進化は作用するので、適切に全体像を掴むのは案外難しい。そこを最適化するにはより上位の役割が必要になる。
そういえば、WIRED の創刊編集長が書いた「テクニウム」はこういった広い範囲でのテクノロジー・マネジメントを行う上で非常に示唆の多い本だった。去年の「技術と創造の設計」に続いて技術それ自体の捉え方を扱った本としておすすめしたい。
Wantedly の振り返り
上記のようなお仕事も8月いっぱいで終了している。
Wantedly では本当に優秀なエンジニア、そしてデザイナーと働くことができた。
ジュニアエンジニアとしては DHH の言うところの Preventing messes / Making great software を地でいく経験ができた(もれなくSaving money も付いてきたが笑)。同期にもとても恵まれた。
3年目には当時、新卒2年目だった @izumin5210 と @qnighy をメンバーにバックエンドチームを持ち、大規模なシステム設計を経験した。この2人がいたことで自分はソフトウェア設計からアーキテクチャ設計に明確に重心を移すことができたと思うし、どんなに複雑に見えるシステムも真因を明らかにして適切な処置を施すことで対処可能であるという確信を持った。
4年目には3つの(今でいうところの)ストリーム・アラインド・チームをまとめるリーダー of リーダーになり KPI を持って1つのプロダクトを伸ばすということができた。プロダクト作りとプロダクトマネジメントの違いをここで学べたと思う。
その後は必要性もあり全社の技術戦略やアーキテクチャをマネジメントを行ったがこれもこの記事に書いたように多くの学びがあった。
ここには挙げなかった人、直接一緒のチームで働かなかった人も含めて学んだことが多い。そしてもちろん、こういった組織を作り上げた CTO の @kawasy にはとても感謝している。
以上に加えて、教えるということにも多くの学びがあった。特に技術フェローになってからの1年は現開発執行役員の @nory_kaname がそれを組織的に実行するのを横で見ていたが、組織設計とピープルマネジメントについては最後の2年が最も学びが深かったと思う。
初期パラメーターが高い人だけ選び続けてもそれは何かを生み出しているかというと疑問があるし、マクロに考えれば、最終的に良いソフトウェアエンジニアをきちんと育てて増やすということに尽きる。
この点では、自分は大学時代から既に恵まれていた。研究室の先生は何か新しいことをやったらそれが役に立つかの判断よりも先に「それ、面白いね」と言う。そういう中で色々な面白いソフトウェアを作る人がいて、そういう人が時々すごいソフトウェアを作っていた。
企業レベル、つまり資本主義の世界でも技術を育める文化を持つ会社が、きちんと技術を事業的な価値に変えてかつ資本的にも還元して拡大再生産していくことが必要だというのが1エンジニアとしての意見だ。
SANU に入社した
さて、9月からは SANU という会社でソフトウェアエンジニアとして働いている。
リリース当初に申し込んでずっとユーザーだったのだが7月にユーザー向けのイベントに行ったことがきっかけで、代表の Gen さんやファウンダーの Hilo さんとお話しして非常に面白かったので入ることにした。
自分にとっては、前職の経験はありつつも普通にソフトウェア開発の方法論を難易度を上げて適用するのはちょっと面白味がないなと正直感じていた。そういう意味では、SANU には自分が働いたことのないような人たちがたくさんいる。
サービス運営の中でも、アプリの開発をするファンクションも必要なのだが、リアルなオペレーションがあり、建築があり、不動産としての運営があり、それが総合的なユーザー体験と収支に紐づく。
こういう世界において、例えばチームトポロジーの方法論でストリーム・アラインド・チームを作ると言ってもどう適用するかは全く自明ではない。ただそれでも入ってみてきちんと観察をすると、オンラインでのフィードバックがめちゃくちゃサービス運営に活きていて、改善につながっている。
ここにデータの活用、そして継続的デリバリー、プロセスをシフトレフトさせて作り手の発想を入れるといったエッセンスのレベルでは加える価値があるのも明らかで、むしろリアルなお客さんがいること、現実に受けるサービスの一定割合はそういったものであることを考えれば、サービス開発の本丸では?とさえ思う時がある。
・・・と SANU に入ってからの発見と驚きはもっと伝えたい気持ちがあるのだが、普通に記事がもう1つ出来てしまいそうので、一旦このあたりで。あ、もし気になる人がいれば喜んで話すので直接声をかけてね。
0 notes
takenos · 1 year
Text
2022年に使ってみたサービスとか
2022年にやっていた趣味的な取り組みの記録(仕事のことはこちら)。ゆるふわに書いていきます。
サービス - 消費型サブスク部門
仕事以外の時間が増えたことで、例年と比べると試したことが多かったため、今回はちょっと部門別に分けてみた。
まずはサブスクの中でも、消費するモノが送られてくる系。
コーヒー豆:PostCoffee
前年に Starbucks Reserve で色々コーヒーを飲むようになった結果、途中から「自宅で作れれば良いのでは?」ということに思いが至ったので、Post Coffee を導入してみた。毎月3種類、コーヒー豆が送られてくる。こんな感じ。
Tumblr media
途中から、コーヒーミルを買って自分で粉にするようにした。ちょっと作ってる感あって楽しい。味の違いは分かっていない。
マグカップも Reserve で出されるものを購入したので、この領域は自分の中で完成した感がある。
完全食:BASE FOOD
仕事をしていて、朝の食事を簡易に済ませたい場合などのために、完全食を導入してみた。
モノとしては悪くはないかな・・・という感じで続けるかはちょっと分からない。こういう感じ。
Tumblr media
ところで、この手のサービスには、大体商品ストーリーとかを伝えるジャーナルがついて来ているのだが、個人的にはそういうのはあまり読んでいない。つまり、BASE FOOD について D2C / Direct to Consumer であることのブランド的側面にはそこまで惹かれていない感じがする。ただこれは単純に、自分が「プロダクト」としてそこまで好きになっていない、というのがあるのだろう。
個人的な期待としては、ユーザーにより近いというメリットを活かして、「プロダクト」が継続的に改善されて良くなっていって欲しいなと思っている。それが継続すれば開発ストーリーにも興味を持ち、個々のプロダクトを超えて「ブランド」のフォロワーになることもあるかもしれない。
リラクゼーションドリンク:チルアウト
逆にこれはプロダクトとして好きだったやつ。
Amazon の定期配送を利用して購入していて、風呂上がりの睡眠前に飲んでいたのだけど、突如通して在庫切れになってしまって QoL が爆下がりしてしまった。
今になって調べてみると、プロダクトのラインナップが変わったことによるものだったらしい。僕はこのプロダクト(とたぶんそのブランド)が好きだったので、「プロダクトラインナップの移行」に誘導されずに「在庫切れ」に誘導されたのは、サービスとして機会損失だったし、もっと良いコミュニケーションがありえた気がする(何せ実際に買うのをやめてしまったので)。
今の Amazon の小売のスキームだとこういう風にしかならないので、ブランドと消費者をつなぐ小売のアーキテクチャはもっと良くできる余地は少なくともありそうだ。
サービス - 空間型サブスク
セカンドホーム:SANU
消費されるモノではなく、ある空間を自由に使うことがサブスク化されていることがある。一番身近いなのは家の賃貸だが、このサービスは 2nd Home というコンセプトで、自然の中に2つ目の家を持つことを提供している。
Tumblr media
これは抽象レベル(ビジネスモデルのレベル)では、別荘のシェアリングエコノミー的なやつだと思っている。普通に持つとすごいお金持ちしか得られない別荘だが、実際に使われる割合は少ないので、シェアすることにとても合理性がある。
サービスとしてはどの場所に行っても気兼ねなく暮らせるように全部同じフォーマットになっていて、料理器具や調味料なども一通り揃ってる。
それもあって、2022年は SANU 限定で料理を始めた。
Tumblr media
コワーキングスペース:SHARE LOUNGE
徒歩10分の恵比寿ガーデンプレイスに出来たので利用し始めた。厳密には、これはサブスクもあるけど、今のところ買い切りチケットで不定期利用している。
2023年はどこかで We Work も一度使ってみたいと思う。
サービス - モビリティ部門
カーシェア:Anyca
退職後の有給期間を使って、車の免許を取得した(実は10年前に取って時限失効していたので再取得)。
この経験はいろいろ面白かった。まずプロダクトとして見ると車というのはセンサーに足りてないところも多いのだけど(後方10mが死角だったり)、人間という高度なパターン認識学習器をトレーニングすることで解決している。また、運転教本を見ていると、重大な事故に対しては2重にロックがかかっていて、両者が想定から逸脱した場合に事故が起きるような設計になっている。
一見すぐにエンジニアリング的に解決したくなるところが、長い時間の中で人間的・社会的に解決されていて、それが車の基本デザインと運転教本に凝縮されているのが感じられてすごいし、逆に自動運転車みたいなものを作りたくなる気持ちも理解ができた。
自動運転といえば、元々 Tesla に乗ってみるという目的があったのだけど結局乗らなかったので、2023年には乗りたい。Anyca で個人が貸し出していたりする。
電動キックボードシェア:LUUP
ここ2-3年ソリューションを探していた課題として、都心部の1-2駅程度の移動をするのに電車が向いていないということがある。駅近じゃないというのもあるし、白金台駅周辺は乗り換えが多いという事情もある。
そのために一時期は自転車を購入してみたりもしたのだけど、ある駅に自転車を置くと必ずその駅を経由して戻らなければいけないという制約が結構厳しくて、結局近距離なのにタクシーを利用してしまっていて、コスパが悪かった。
これを解決してくれたのが LUUP で、最近は基本的に近距離はこれで移動している(免許を取ったので乗れるようになった)。
コスパ良いし、個人的に東京の街は好きなので、街を見て楽しめている。
Tumblr media
サービス - 決済部門
2022年は最適でシンプルな決済手段とお金の流れを模索した年でもあった。ただ、結論から言うと、この領域は魔境だった。利用者から見て暗黙的な機能や、試してみないと動くか分からない(動くものと動かないものがある)といったことがすごく多かった。
なんとかリファクタリングを続けて現状こうなっている:
Tumblr media
単純な理想を考えると、全部単一のクレジットカードに集約して、インターフェイス違いになることだったりする。
でも、スターバックスくらいになるとクレジットカード手数料を払いたくないのもわかるし自前でアプリ開発できてしまうので、こうなるのも仕方ないところがある。
とすると、一つのシステムに集約するのはなく、システム同士がきちんと連携する規格があり、それによってユーザーに選択権と利便性がもたらされる、という方向に進むと良さそうだなと思った。
プロダクト
AR/VRヘッドセット - Meta Quest Pro
これは結構買ってよかったやつ。仕事用のディスプレイの代替として使っていて、普通に使えている。このため、職場も自宅も物理ディスプレイは撤去してしまった。
Tumblr media
これが目的だったから良いのだが、誰も周りに Quest Pro を買った人がいなくてソーシャルな機能は全然試せていない。これ読んだ人で持ってる人がいたら Horizon Workroom でお話ししたい。
ちなみに、2時間以上つけているとおでこがかなり痛くなるという致命的な欠陥がこのプロダクトにはあるので、長く使う場合は重みを分散させるように改造する必要がある。
ゲーム
某ゲームのオンライン対戦環境を整えたのも2022年だった。こんな感じ。
Tumblr media
アーケードコントローラ:ファイティングエッジ刃
これはとても良いプロダクトだった。
Tumblr media
YouTube 配信
配信機器を買って時々配信している。音声やらストリーミング動画を合成するソフトウェアに詳しくなった。
配信といえば、��度界隈の有名プレイヤーのチャンネル配信に出たのだけど、スパチャ(投げ銭)が一度に5万円くらい飛んできたりして、世界観がアップデートされる体験だった。
教養
最後に教養的に学んだこと。
技術:2022年はビットコインとスマートコントラクトを勉強した。最近は機械学習・深層学習を改めて勉強している。
社会:2022年は世界史をやった。最近は経済についてもう少し知りたい。
Tumblr media
世界史の整理の中で、記憶術全史で得た知見を Miro で試用してみるなどしていた。
ということで(?)、2023年もよろしくお願いします!
0 notes
takenos · 1 year
Text
2022年の仕事のふりかり
例によって2022年の振り返り。まずは仕事のことを簡単に。
仕事
社員として
事実を振り返ると、1月はフルタイムで React / TypeScript で Web アプリを書いていたようです。検証したかったのは、全体のアーキテクチャを Web アプリや Mobile アプリとバックエンドのシステムに分離する構造が本当にデリバリー・パフォーマンスを十分向上させるのか?であり、大きめのプロジェクトで自分で確かめつつ、デモンストレーションをしました。
また、インフラチームの次期体制構築のためにリーダーを一時的に兼任したのですが、ウォンテッドリーで唯一これまで自分が直接やったことなかった技術領域だったこともあり、点と点がつながることが多かったです。いま思えば、この領域が自分にとってアンロックされたことで全体がシームレスに設計できる対象になった感があります。
他にも、退職するまでエンジニアリングマネージャーの一人でもあったので色々やっていたのですが省略します。
退職
ちょっとだけ過去から振り返ると、ウォンテッドリーには2015年3月、確かこのときフルタイムのエンジニアが10人行かないくらいだったと思いますが、そのタイミングでインターンに来ました。プロダクトについて言えば、グロースから始まり機能開発、マネジメントとやりました。
また、最後の3年間は、年間/四半期の方針を決める経営会議にも出ていたので、レイヤー的にも割と上から下まで関わったのかなと思います(一応株式会社的にはその上に取締役会があるのですが)。
その上で、前年プロダクト開発で見つかった全体の技術課題を解決することを最後の仕事として、区切りをつけることを考えていたのですが、この時期 CTO の退任など色々重なったこともあり技術マネジメントについては継続することにしました。
自分個人としては、これはこれで明確に領域を定めて少ない時間で高いバリューを出すという意味では良い試みになるかなという予感がありました。
業務委託として
そんな経緯もあり、9月からは技術フェローになりました。内部的には VP of Technology の責務を一定担っています。
VP of Engineering の役割はよく聞くと思いますが、ウォンテッドリーはテックカンパニーとして、技術的な観点を踏まえた全社経営方針があり、それをソフトウェア・システムと開発組織の両方に結合するような体制設計にこの年の9月からなっています。このうち、経営方針とソフトウェア・システムを結合するのが VP of Technology の役割です。
組織的には、各技術領域や横串の技術基盤チームの上に配置されるような構造で、実際にこれらのリーダーと仕事をすることが多いです。技術戦略の下地はもともとアーキテクト時代に作ってあったので、実際にそれが自律的に推進されるように視点をインストールするようなメタ的な活動を心がけています。
このあたりのアウトプットは2023年からちょっとずつ出せるかなと思っています。
今後のこと
空いた時間で何をやっているのかよく聞かれるのですが、ウォンテッドリーに7年いた間に世の中も結構変わったなと思っています。この会社を選んだ時は、自分なりの時代文脈の解釈と課題感に基づいて決めたわけですが、そう言った理解をまずはアップデートしておきたいと思っています。
大きく言うと、1)日本にある課題のマップを自分の脳内に作る、2)世界についても粗くでも同じことをする、3)それらに対して情報技術がどうアプライされるべきかの自分なりの見立てを作る、4)そこに対して自分がどう関わるかを決める、といった辺りです。
もちろん、現実にこんなに綺麗に行く必要はないし実際にはもっと偶発的で良いので、思考のためのフレームとして置いているということです。
この本は素晴らしく良かったですね。2022年の個人的ベストでした。
個人的に、良いソフトウェアエンジニアを増やすために足りないのは、巷に溢れている知識のレイヤーではないと思っていて、もっと基底的なソフトウェアをエンジニアにインストールすることが必要だと思っています。この本は、機械畑の出身の人が書いた本ですが、そういったことが正面から書かれているものでした。ここは今後も自分の考えるテーマになる気がしています。
0 notes
takenos · 2 years
Text
2021年の振り返り
毎年恒例の振り返りをやっておきます(もはやこれだけを投稿するブログになっているが笑)。
仕事
アーキテクトとして
2021年の頭に、ずっとチームで開発していたプロダクトが出せて少し落ち着きました。このタイミングから、明示的に開発組織全体のアーキテクトとして全社的な視点で技術や設計の課題に取り組むようになりました。
もともと Wantedly という会社は、トップダウンにもボトムアップにも活発に新しい技術を試したり導入する傾向があり、そのおかげで最近はバックエンドは Kubernetes ベースの Microservices Architecture が割とちゃんと導入されていたり、Web フロントエンドも GraphQL や Design System のようなものが導入されていました。
ただ、前年のプロダクト開発で、それらをワンセットで利用してみると、個々の技術が(プラスではあるにせよ)本来狙ったほどにはワークしていなさそうだということが分かりました。
個別に見るとそれぞれの技術が解決したい課題というのは確かに存在していて、かつその技術を適切に使えば実際に解決できるであろう、ということもまた確かだったのですが、「その課題は “いまこのステージで” 解くべき課題なのか?」といったことや、「その技術の導入が間接的に及ぼす “ソフトウェア全体への影響” は良い方向の変化なのか?」といったことまでは検討しきれていなかったように思います。
例えば、Protocol Buffers と GraphQL という二つの API に関する技術があるとします。これは、「API のスキーマを記述することで、API に型をもたらす」という点では、同じ課題を解決します。「型がある」というのはプログラマーにとっては(事前の記述コストが許容できるのであれば)ほとんど自明に開発生産性の向上をもたらすので、これは良いことのように思えます。
一方で、スキーマというのは Microservices Architecture のように API を第一とする抽象度が高めのソフトウェア開発スタイルにおいては、ドメインの知識を凝縮したものである必要があります。そうすると、「ドメインの知識の集約」という点で、Web フロントエンドのインターフェイスとなる GraphQL に知識を集約するのか、それとも個々の Microservice のインターフェイスとなる Protocol Buffers に知識を集約するのか、という二つの選択肢が生まれ、これがバックエンドと Web フロントエンドの「分断」を発生させます。
これの本来あるべき状態は、「API のスキーマを記述する」というコストを支払うことで、それが「型がある」というような単純なレベルから「ドメインの知識がソフトウェアに現れる」というような高いレベルまで、そして「Web フロントエンドが嬉しい」ではなく「バックエンドも Web フロントエンドもモバイルアプリも嬉しい」といったようにあらゆる点と面でプラスに働き、それによってスキーマを書くということ自体が加速し、ソフトウェアが成熟していく、というものです。そして、こういった技術の導入と推進の判断は、それが回り出すまでに整備するために投下できるリソースと、それによって生み出される余剰のバランスは戦略的に考えることであります。
ここに挙げたのは一つの例で、他にも「デザインシステム」のようなデザイナーとエンジニアに横断的な仕組みにも同様の大きな可能性と難しさが同居していますし、「データウェアハウス」のようなデータサイエンティストとソフトウェアエンジニアが利用する技術にも、それぞれに異なる要求が存在しています。
このようなことはある程度は元々分かっていたことでもありましたが、Wantedly のプロフィールというプラットフォーム的機能のリニューアルで、プロダクトオーナーと開発責任者を兼ねてみたことでプロダクト開発への影響度を良くも悪くも実感したこともあり、少なくとも向こう1年くらいはこの課題に取り組むことにした、というのが現在アーキテクトというポジションをやっている動機になっています。
なお、現在はそういった背景もあり意図的にプロダクト開発と距離を取っていますが、本来的なところでいうと、ソフトウェア・アーキテクトというのは、こういったドメインから少し距離を取った汎用技術の方向性付けだけではなく(それはもちろん土台として必要なことなのですが)、プロダクトのビジョンや戦略と一体化したものであるべきだ、と個人的には思っていて、そういう方向に世の中のソフトウェア開発も向かうと良いな、と思っています。
適切な概念を選ぶ
備忘のため、主にどういったことをやったかについても少しまとめておきます。
まず一つは、上記のような経緯から、技術領域をまたいだ部分に問題が表出していそうだという当たりがついていたので、各領域のテックリードを集めて「開発をする上で困っていたり、自明ではないと思っている事柄」を一通りリストアップをしました。それをベースに、全体としての現在あるべきソフトウェアの構造と要所要所でどのような技術的解決を図ろうとしているのか、を自分の方でまとめたものが、公開されている資料にも掲載されている以下の図です。
Tumblr media
詳細は公式なブログでいずれ書く気がしますが、これは最も大きな構造で言うと Applications と System と Data という三層になっています。
前者二つは、元々 Frontend と Backend という Web / Rails 由来の相対的な概念がよく使われていたのですが、自分たちのサービス(そしてもしかしたら他のいくつかのサービス)においては、この概念化はあまり有用ではないなと思うようになりました。
理由として、Backend の作り方自体の高度化(e.g. デ・カップリング、Polyglot 構成)、昨今の単にコンテンツを表示するに止まらない Web サービスのアプリ化とそれに伴う (Web) Frontend 技術領域の進化、そして Mobile アプリの存在があります。こういった状況では、「ユーザーの手元で動くプログラムであるところの Applications」「自分たちの Kubernetes クラスタ上で動くプログラムでありドメインの情報を保持する System」という概念化を行なった上で、Application は Web, iOS, Android のプラットフォームごとに提供される(したがって複数存在する)と捉えた方が、意味のある議論がしやすいと感じています。Data という層の導入も、同じように一般的に流通している概念化が自分たちの状況に追いついていないことを反映しています。
個別の問題解決
このような認識の基礎となる概念と基本構造という全体を固めた上で、部分で起きている問題を認識して解決に向かったのが以下の例です。
マイクロサービス・アーキテクチャと共存する Ruby on Rails のアーキテクチャ的拡張 / Kaigi on Rails 2021
GraphQL 導入の反省と再挑戦 / jsconf jp 2021
ただ、こういったカンファレンスに出すのは話題として意味がありそうな新規性の高いトピックに偏るのも事実です。実際の内部は、「(fault-torelance のための) System のマイクロサービス間通信のエラーハンドリング機構の導入」のようなまあ普通にやるべきだよね、みたいなことも進めていたりもします。
ソフトウェア設計の研修
ところで、API スキーマやデザインシステムがどんなに優れたものであっても、その中で実際に行われる設計が正しいスタンスで行われなければ、効果を発揮しません。このため「ソフトウェアの設計とは何なのか」と言うことについてエンジニアの初期に多少なりとも触れておくことは、かなり重要なのではないか(そのようなことに触れないケースが意外と多いのではないか)、とこれまでの経験から思っています。
そこで、できるだけ多くの人が理解できるように、ボトムアップな形でソフトウェアの設計というものについて新人研修で伝えるようにしました。
ソフトウェア設計の Why & What & How
この記事は共感してくれた人が多かったため、自分の感じていた課題意識がマクロ的に存在することを確認することができました。
個人:Web フロントエンドに入門する
2021年は現代 Web フロントエンドに入門しようということで、色々やりました。エディタを Emacs から VS Code に移行(= Emacs だと思って操作して問題ないレベルまでチューニング)するところから始まり、JavaScript, TypeScript, CSS, React, Firebase, Material Design System などなど。Zenn のスクラップ機能、いいよね。
Firebase で Todoist のクローンを作る
モードレスなテキストウィジェットの React コンポーネント設計
ちょうど年末から仕事でも Web フロントエンドがアサインできない中規模のプロジェクトがあったのでメインで書います。この辺りは2022年も少し続けて、UI デザインとかの理解を深めようなかなあと思っています。
生活
サービス
スタバ
2021年は緊急事態宣言が多すぎて夜飲むことが減って朝方になり、朝7時に Starcucks に行くことが増えた。そして Starcucks の上位互換である Starbucks Reserve を恒常的に利用するようになり、1杯1000円近いコーヒーを頻繁に飲むようになってしまった。しかしある意味そのおかげで Web フロントエンドの勉強などが捗ったのも事実。
サービスとしては、Starbucks アプリがよくできており、ロイヤリティを高めてリテンションするためのお手本のような設計になっている。飲食店のインターフェイスはこれからどんどんアプリ化されていくだろうし、そのための共通ソフトウェアは必要になってくるだろうから、あとはどのようなソリューションが良いかという話だと思う。
みんなの銀行
2021年の面白かったアプリで言うと「みんなの銀行」がある。口座の開設手続きが15分程度でアプリ上で完結し、その上で必要な窓口確認業務は In-App Broswer で行う。振り込み通知などが Push 通知で来るのは当然できて欲しい体験ができている感じが良い。また、デビットカードが発行されるためそれが Apple Pay に接続できる。
集計をしていると思うんだけど実際に使った時期とお金が減る時期がズレるクレジットカードというのは不便でしか��くて、お金が動くパイプラインはもっとシンプルになるべきだと思う。そういう意味で、一番根っこになる銀行の部分がデジタルでないのがネックであって中間的なソリューションを生んでいる原因な気がしたので、この部分からのイノベーションは期待したい。
SAKE POST
今年はサブスクリプションだとこれくらいかな?半合くらいの日本酒パックが月に3つ届くので、ちょうど良いなと思っています。サービスとしてみた時の定期消費のサブスクリプションはパーソナライズの仕方がまだ見えていない感じがあって、例えば個々に消費するユニット数には違いがあると思うのだけど、それにどのように対応するのかと言うことが自明ではない。ここは追跡ができないということからデジタルサービスと違う難しさを感じる。
(ちょっと力尽きてきたので、ここから雑になる)
2021年に読んで良かった本だと、落合陽一の「デジタル・ネイチャー」がある。何というか、読んでいて全般的に思考のベクトルが近いなと感じだのだが、今まであんまりそういう風に思うことってなかったので、それが個人的に発見だった。
Tumblr media
デジタルネイチャー 生態系を為す汎神化した計算機による侘と寂 )
落合陽一 PLANETS/第二次惑星開発委員会 (2018/6/15)
Amazon.co.jpで詳細を見る
ゲーム
PS5 で「ゴースト・オブ・ツシマ」「戦国無双5」「十三騎兵防衛圏」「ジュラシックワールド2」をやった。「十三騎兵防衛圏」はあまりやったことのないジャンルで、そういう意味でやれてよかった。やってて薬師寺恵かわいすぎない??ってなったけど、調べたらこれはそういうものらしいので良かった(?)。
0 notes
takenos · 3 years
Text
2020年ふりかえり
例によって、少し遅れて一年の振り返り。こういうのは続けていくことで積み重ねることでそのときそのとき自分がどう思っているのかを残しておくことが大事(という普段よく聞くラジオの受け売り)。
仕事
2020年にやった主な仕事はウェブとアプリのプロフィールのリニューアルでした。ほとんどプロダクトのことを考えていて、めちゃくちゃ仕様をかいたので、仕様を書くのは少し得意になった。
ウェブの方のプロフィールは Wantedly の採用のプラットフォームとしての中核価値になっている既存機能であったため、難易度が高めで面白かったです。ひとつは守りの側面で、リスクの洗い出しから段階的なリリース戦略の策定と検証をかなり綿密にやりました。こういう UI/UX を変更する重要機能のリニューアルはひとつ間違うと要らないところで大きく炎上したりして失敗するので、UI課題などを各段階で適宜クリアしながら進めていきました。やりたいことが100%やれたかというと全然満足はできなかったけど、ひとまず着地はさせることはできたかなという感じ。
攻めの側面でいうと、すでに10年近く使われてる機能のリニューアルであり、最低でも5年は使われるであろうことから、「最初の決め」で今後の可能性が決まってしまう部分についてはかなりアグレッシブに仕様を決めました。いろいろなプロダクトをみていたり、自分でも開発していたりして、発展可能性というか、そのプロダクトが持っている “射程” ってやっぱり確実にあるなと感じるんですよね。自分は、せっかくやるのであれば大きな可能性があるものをやりたいと思うので、スコープを爆発させないようにしつつやるべきことはやることをプロダクト判断では重視しました。
ちなみに去年に自分が立てた GitHub イシューをざっと眺めてみたのですが、仕様を書くみたいなところから、その仕様がどういう指針に基づいて導かれるのか、それはなぜなのか、といった抽象化にたくさんチャレンジしていたようです。例えば、プライバシーに関わる仕様を決めたときには、自分たちのプラットフォームはどういう体験を提供すべきか、どこを目指すか、というところまで上げないと、継続的にプロダクト・マネジメントが行えないと感じました。また基本的に自分は怠惰なので自分がやらなくて良いことは自分がやらなくて良いようにしたいという行動原理に基づいているので、その時に仕様を決めるのではなく仕様を決めるための考え方を規定できれば良いのでは、とも思いました。
これはまだ途中の試みですが、仕様を書くという時に 1) 実装ができるようにちゃんと詰めるべきところを詰める、2) 排他的なプロダクトの判断をする、の2点があるような気がしています。前者は分解、後者は分岐。ひとまずたくさん仕様を描いてみて分解をうまくするためのフォーマットみたいなのは作っていて、これでだいぶ再現性が上がったなと思う一方で、後者はまだ難しさを感じているのが現状です。
あと、それでいうと、モノを作るということってどういうことだろう、っていうのを若干考えるようになったのも去年でした。きっかけとしては 「INSPIRED」という本を読んだのですが、ソフトウェアで価値を作るための要諦が書かれていてすごいなと思った一方で、これにそのまま従うのではなく、自分の頭と経験でちゃんとそこは考えた方が面白いなと思ったのでした。
Tumblr media
INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント )
マーティ・ケーガン,佐藤真治,関満徳 日本能率協会マネジメントセンター (2019/11/1)e
Amazon.co.jpで詳細を見る
ちょっと毛色が違うことでいうと開発組織がひとつに再編されたときに、組織全体のコミュニケーションを設計するという仕事をアドホックにやりました。これはかなり成果が出たので、いずれどこかでブログ書くかも。ここでの気づきは、構造とコミュニケーションというのはセットで、それはソフトウェアのアーキテクチャや責務を設計するときの手順とかなり近いものだということでした。おそらく、“ソフト” なモノに対して人間が記号や形式を与えて処理可能にするようなところに一定のお作法があるのだろうと思います。
抽象的なことばかり書いたけど、機能のリニューアルにあたってマーケティングのプロジェクトに関わったのもあって、どういう順番で何を伝えるのか、ということも大事だなと実感できたのも去年良かったことでした。自分は習性として因果関係の一番深いところから考えがちなのだけど、それ自体がひとつのフレームであって、もっと手前のところから発想するやり方もあると気づきました。ここをフラットに見れるようになったことで、以前より自分のやり方に固執しなくて済むようになりそうな予感がしています。
生活
サービス
パンのサブスクリプションサービス:パンスク
リモートになって豊かな朝食を実現したくてパンのサブスクリプションサービスを使いはじめました。美味しいパンが毎月全国の違うお店から10個くらい冷凍で届いて、オーブンで焼くと良い感じになる。同じパンを食べ続けると飽きちゃうので、中身をランダムにするという工夫がサブスクリプション化の過程で行われていて、サービス設計の観点でも興味深いなと思います(これ系でおもしろいサービスがあったらどんどん試していきたいのでオススメがあれば知りたい)。惜しいところがあるとすれば、今後このパン屋さんのこれを継続的に購入したい、みたいに思っても術がないところ。そういうのが生まれれば、パン屋さんにとっても嬉しいし、もっと良いサービスとビジネスが作れるかも?と思ったりします。パンじゃなくても、これ系のサービスはそこを突破できるともっと面白くなると思う。
洗濯代行サービス:しろふわ便
去年推しだった家事代行サービス Casy の人に教えてもらった洗濯代行サービスが良かった。家事代行のほとんどの部分が洗濯だったのと、家事代行だと干すところまででたたまなきゃいけないという課題があったのですが、このサービスはそこを解決してくれます。どういうことかというと、四角いバッグに洗濯物を雑に詰めて宅配ボックスに入れておくと、回収されて折りたたまれた状態でまた宅配ボックスに返���て来る。宅配ボックスに何かを入れておくとよしなに処理されて宅配ボックスに返って来るというの、なかなか体験として面白いし、実質洗濯機の上位互換なので、洗濯機要らないのでは?と思い始めています。しばらく運用してみて洗濯機使うシーンがなければ、捨てて別のスペースにしてしまおうと思いました。
ゲーム
いままで家にあんまりゲームを置かないようにしていたのですが、Switch を買った時からその抵抗は無駄だったことに気づいたため、今年は思い切って PS5 を買いました。今のところ「スパイダーマン・マイルズモラレス」「アサシンクリード・ヴァルハラ」「ゴースト・オブ・ツシマ」という風にオープンワールド系を買っていて徐々に遊んでいる。「スパイダーマン・マイルズモラレス」、買ったは良いけどマジで何もわからなくてニューヨークの街が綺麗だなとしか思えなかったので、マーベル・シリーズに入門した方が良いかもしれない。
2020年は世界史頑張ろうという気持ちでいて、歴史系の本をいくつか読むことができた。春あたりウォーラーステインの「近代世界システム」を読もうとしてヨーロッパ史なんもわからん・・ってなって、出口治明さんの「『全世界史』講義」を読んでから再度戻ってきた(忘れていたけど、自然気胸という病気で入院して手術をしている間に読んだのだった)。あとは個別だと「反知性主義: アメリカが生んだ『熱病』の正体」と「『帝国』ロシアの地政学 − 「勢力圏」で読むユーラシア戦略」とか。まだまだ全然大したことはないのだけど、ニュースや論説を見たときに以前よりちょっとだけ自分なりに文脈に位置付けて解釈できるようになって、解像度が上がって楽しい。
Tumblr media
近代世界システムI―農業資本主義と「ヨーロッパ世界経済」の成立 )
I・ウォーラーステイン (著), 川北 稔 (翻訳) 名古屋大学出版会 (2013/10/15)
Amazon.co.jpで詳細を見る
0 notes
takenos · 4 years
Text
2019年ふりかえり
例によってお正月なので2019年のことをまとめておくことにします。
仕事
今のプロダクト開発チーム(Wantedly People)にジョインしてちょうど二年くらい経ちました。去年の今頃は何をしていたかと言うと10人4ヶ月くらいの大型プロジェクトの真っ最中で、プロダクトを大幅にリニューアルしていました。これは予定通り2019年の3月末にリリースすることができました。
Wantedly ではエンジニアとデザイナーがそれぞれプロダクトマネージャとプロダクトデザイナーとして動き、一緒にプロダクト設計をすることが多いのですが(最近新しい版が出た INSPIRED でも紹介されている典型的なプロダクトチームのパターンですね)、このプロジェクトもその形でした。その中で自分がプロダクトマネージャ的な立ち位置で、コンセプト設計からドメイン設計まで、設計全般に関わりました。競争優位性や事業としての親和性を踏まえると、スタンドアローンで使うツールから何らかのピボットする必要があることが認識としてありましたが、「では何を作るべきなのか?」というところから実際にコードを書いて作れるところまでを落とす仕事です。
この過程で、Facebook や Twitter と言った SNS の構造をかなり解像度高めで見たのですが、これはエンジニアとしても学びがありました。例えばですが、Facebook は「ユーザー」以外もコンテンツ生成主体になれるんですよね。例えば Facebook ページ。この構造は更に Like のようなエンゲージメントアクションの対象も任意のものになる(技術用語で言えば polymorphic になる)。この辺りのほぼプロダクトの基本設計と言って良いような構造がバックエンドの構造(例えばグラフデータベース)と連動していたり、広告の出し方のようなビジネス面にも関わってくる。ユーザーインターフェイスの潮流としてもスキューモーフィズムが薄れたりデザインシステムのような概念が普及していますが、大きな流れとして情報を扱うプロダクトはどんどん抽象的になっていっていると僕は思っています。プロダクトの細部をどのようにモデリングをするかというような抽象的な話はどちらかと言えば「目的」ではなく「実現方法」として捉えられがちですが、プロダクトの種類のよってはその関係が大きく変わるなと感じた経験でした(こういう気付きを得てみれば、Facebook のニュースフィードの設計者であるクリス・コックスや、Twitter の設計者であるジャック・ドーシーがどちらもソフトウェア・エンジニアであったのは腑に落ちるところです)関連して、そのような設計はどの程度発明され尽くしたのか?というのはソフトウェアを設計する人間として個人的に関心を持ったところです。
無事リニューアルができた後は数字を見ての改善フェーズになって、多くの細かい施策プロジェクトが走るようになりました。この辺りで性質が変わってステークホルダーとのコミュニケーションが上手く行っていかなくなったので自分がプロジェクトマネジメントもやるようになりました。プロジェクトマネジメントと言っても一種の問題解決であって、プロジェクトというもののモデル化から制約条件の確認、運用フローの設計、及びそれに基づいた情報システムの設計、みたいなところなので、普通にエンジニアのスキルを転用しています。プロダクトマネジメントとプロジェクトマネジメントは分けられないのが基本で、後者だけを違う人にやってもらうというのは難しかったなあというのが個人的な学びです。仕事が増えてどうしても、とか社外にステークホルダーがいてデリバリーがクリティカル、とかそういうケースじゃないと基本は分離しない方が良いですね。YAGNI 的な考え方は組織の設計でも大事。
そう言えば僕は自分の中で勝手にメンターに設定している人が昔から何人かいるのですが、2019年に読んで面白かった本の一つに読書猿さんが書いた『問題解決大全』があります。この本では問題解決を2種類に分けていて、なにか根本原因があると仮定する問題解決をリニアな問題解決と言っているのですが、そうじゃない問題解決があると言っている。そういうものをサーキュラーな問題解決と読んでいて、これは因果関係がループしたりしているもののことを指しています。例えば人間の認識などはどんどん強化されたりしていくので、そういうのは構造自体を組み替えてあげないと解決しない、とかですね。銀行の取り付け騒ぎとかが事例として挙げられていますが、このとき取り組んだプロジェクトマネジメントも、そういう種類のものでした。
思えば、2018年に取り組んだマイクロサービス・アーキテクチャの問題解決もその手のことを無意識に考えていて、このときそれを意識化することができたな、と思っています。例えばエンジニアもコードが読みにくいと簡単に実装箇所を変えたりしますよね。それは単体で言えばただの現象なんですが、そういうものが場合によっては負の因果ループを形成してどんどん悪い状態になる、みたいなことがある。だからそういうときは初手・二手目とどう打っていくのが良いのかが単に目に付きやすいところ・見た目のインパクトが大きいところに手を付ける、という動き方では最善手ではないときがあって、そこは複雑な問題を解決をするときは考えなきゃいけないところだと思いました。
Tumblr media
問題解決大全――ビジネスや人生のハードルを乗り越える37のツール ()
posted with amazlet at 20.01.01
読書猿 でじじ発行/パンローリング発売 (2019-09-14)
Amazon.co.jpで詳細を見る
そんな感じでプロダクトに加えてプロジェクトも見はじめたので、年の中頃から正式にプロダクト開発チームのリーダーになっています。マイクロサービスになっているバックエンドは強いメンバーが揃ってきたのでほぼ渡しました。今はサービスとしてのコンピテンシーに関わりそうなアーキテクチャや、プロダクトの方向性に関わりそうなドメイン設計だけ関わっています。そしてそれを実現するための具体的な手段として Protocol Buffers の API 定義のコードオーナーになっています。これはリニューアルのときにも強く感じたマイクロサービス・アーキテクチャの利点の一つで、プロダクトマネジメントの手段としてのアーキテクチャマネジメントと、それを実現するための具体的なインターフェイスとしての Protocol Buffers が割と必要十分な道具になるという話は、どこかで一度 LT してみたいところ。可用性の観点でも結局全てを守ることはできないので分割して管理しようねという話で、じゃあどこを変更してもどこが落ちないことがプロダクトとしてあるべき状態か、というようなこともアーキテクチャの話に乗ってきますが、その辺はありがたいことにセンスの良いエンジニアがいるのでポイント・ポイントでコミュニケーションを取るくらいで済んでいます(余談ですが、マイクロサービス・アーキテクチャの SLA 定義とかってどう障害分離されているかみたいなことがすごく関わってくるのですが、その辺りを形式的に記述するにはどうすれば良いんでしょうかね)。
逆に正式にリーダーになってからやるようになったことは色々あるのですが、プロダクトの戦略策定や暗に存在したビジョンの言語化といったコンセプチュアルな部分はそれを作るだけでなく伝える過程も含めて新しい学びがありました。作るという点では『ストーリーとしての競争戦略』という本を読んだのですが、これの競争優位性の議論がテクノロジー・カンパニーとは?というようなテーマにもつながる話で面白かった。伝えるという点では、その手のことを優秀なメンバーにどんどんインプットしていくと動き方や話す内容が変わっていくのがわかって素直に人が成長するってすごいなという驚きがありました。もちろん必要であれば認識合わせや期待のすり合わせはそれまでもやっていましたが、このときはポジティブな意味でピープル・マネジメントも悪くないなと思った瞬間でした。あと全体的にこの手のことを通して、言語化能力が1年通してかなり上がったという感覚があります。
Tumblr media
ストーリーとしての競争戦略 優れた戦略の条件 (Hitotsubashi Business Review Books)
posted with amazlet at 20.01.01
楠木 建 東洋経済新報社 (2012-05-10)
Amazon.co.jpで詳細を見る
おおよそこんな感じの1年間でした。2020年はより比重をプロダクトに寄せていきたいなと思っています。
補遺:マイクロサービス・アーキテクチャの整理
マイクロサービス・アーキテクチャにまつわる総括的なところも個人的な関心として活動をしました。一つは、『 コンピュータプログラミングの概念・技法・モデル を読む会』というものを半年くらいかけてやりました。これは1人のソフトウェア・エンジニアとして自分が社内外問わず感じた課題感なのですが、マイクロサービス・アーキテクチャのような形でシステムを作るとなったときに、どのような計算のモデル化が当てはまり、それに対してどのような技法があり得るのか?というような視点があればもっと上手く行くケースがかなり多いなと感じています。特に、並行プログラミングと分散プログラミングの特性や、同期通信と非同期通信などのコミュニケーション・パターンなどを知っておかないと、クラウド系のコンピューティングサービスの技術選定の際にも行き当りばったりにしかならずまともに技術戦略を立てることが難しいのでは、とすら思います。
この会では、紹介されたモデル化を HTTP や三層アーキテクチャなど種々の既存技術についても当てはめて社外の参加者の方とも色々ディスカッションをしたのですが、今の Web 技術の進化の形はかなりの程度その誕生背景に影響を受けていて、今後も慣性を持ちながらも要素技術のレベルで段階的に調整されていくだろうというような見通しを持つことになりました。
そういった活動とは別に、2018年から2019年の大規模改修までに得たノウハウのアウトプットも行いました。動機としては、相対的に見えるとマイクロサービス・ネイテイブで開発されたサービスというものが2019年時点では相当少ないし、本番稼働して継続的に変更を加え続けたときのノウハウみたいなのはより少ないなと感じていて、それ故に必要だった整理というものを公開した形です。技術書典7に出した『WANTEDLY TECH BOOK 7』に「最近のソフトウェアエンジニアリング事情」として執筆したものや、それの抜粋である『Wantedly における Go 導入にまつわる技術背景』などがそれです。
より視点を拡げて見れば、昨今のアプリケーションはスマートフォンのような小さな画面の中によりシステマチックに多くの価値を詰め込む傾向があるように感じていて、それと並行して推薦やデータを扱う技術の価値というものがアプリケーションの価値に直結することも多くなっていると感じています。ここに一定のフロンティアがあるとすれば、バックエンドのシステムというものはより複雑化する方向に行くと考えられるので、分散システム化を進める要因になっている、というのが自分の今の考えです。ただこれは末端のインターフェイスの変化も関わるので、ある程度は今のスマートフォンを前提にした議論ではありますし、クラウド系のコンピューティングサービスが何をどこまで提供するかというような先端をよく観察した方が正しい結論が出せる気がしています。この辺りは今の自分のフォーカスからは外しているのでそれ以上は見ていませんが、変数が多いが故に今後が楽しみな領域だなと思っています。
生活
サービス
自分的2019年、生活に破壊的な貢献をしたサービス2選です。
家事代行サービス:Casy
隔週で利用しています。家事代行サービスの何が良いかと言うと、どんなに忙しくてもかならず2週間に1回は部屋がきれいになること、それがとても大きなメリットだなと思っています。だいたい忙しくなると散らかって散らかると余計に気にしなくなる、というようなループがあるんですが、Casy は定期的に同じ人が来るのが基本のシステムなので、それが起きない。2018年に DMM おかん を利用したこともあったのですが、これはアドホックに呼ぶサービスでした。アドホックに呼ぶとなるとそもそもスケジュール調整とかしなくちゃいけなくて利用ハードルが高いし、忙しいときほどそれもしたくなくなる。あと DMM おかん は毎回違う人を呼ぶので、そこの調整コストも高い。全然サービス設計の良さが違うんですね。結果的に DMM おかん はもうサービス終了しちゃいましたが、少なくともデフォルトでサブスクリプションにするのが家事代行サービスをデザインする際の必須要件だと思いました。はい。
宿泊予約サイト:Relux
2つ目は Loco Partners が利用する Relux です。よく Wantedly で募集出してたので DL してみたという経緯。これは何が良いかと言うと、イケてる宿しか載ってないことと、その中でも値段とは独立に品質を5段階で格付けしているところ。コストパフォーマンスという言葉で言えば、`コストパフォーマンス = パフォーマンス / コスト` で、このパフォーマンスの項のみを評価してくれてるのがありがたい。パフォーマンスで絞り込んだあとに最後にコストを見れば良いので個人的なニーズに合っている。あとは普通にアプリがあって今どきっぽくて便利。どうでもいいけどアプリの UI のチューニングは結構工夫してるなと思う割に検索はリレーショナルデータベース使ってるのか?っていうくらい遅いので改善してあげたい。“旅館” みたいな出現頻度高めのワードでクエリを投げると壊れるのでだいたい何が起きてるのか分かってしまってかわいそう。まあいいや。サービスとして見たときの個人的になるほどと思ったポイントで言うと、扱う宿の数を絞る → 一つあたりの評価にかけられるコストが増える → 信頼性のある評価が可能になる、という戦略になっているように見えます。普通は扱う宿の数は多い方が良いと思うところですが、この定説をひっくり返すことでサービスとしての強みを作り出しているのが面白いですね。
良い。 pic.twitter.com/PSB98VRTMV
— Sohei Takeno (@Altech_2015) April 23, 2019
リゾートに来ている pic.twitter.com/rAutqD5ABZ
— Sohei Takeno (@Altech_2015) September 20, 2019
僕のこのサービスの使い方は4泊くらいしてそこで好きな本を読む、っていうので、これがめちゃくちゃ良かったので2020年も習慣として続けようと思っています。
かれこれもう5年以上積ん読していた若桑みどりさんの『クアトロ・ラガッツィ 天正少年使節と世界帝国』という本があるのですが、これを Relux で宿泊した宿で読みました。これが本当に素晴らしくて、これでちょっと歴史趣味が再燃しちゃってます。良い本や物語に出会えるのは人生の主要な楽しみの一つです。
Tumblr media
クアトロ・ラガッツィ 上 天正少年使節と世界帝国 (集英社文庫)
posted with amazlet at 20.01.01
若桑 みどり 集英社
Amazon.co.jpで詳細を見る
Tumblr media
クアトロ・ラガッツィ 下 天正少年使節と世界帝国 (集英社文庫)
posted with amazlet at 20.01.01
若桑 みどり 集英社
Amazon.co.jpで詳細を見る
ゲーム
GW くらいから手を付けた『シヴィライゼーション VI』が沼でやばい。最近は MOD のリアルマップを DL して遊ぶのに少しハマっている。例えばユーラシア大陸のマップでモンゴルでプレイすると、ゴビ砂漠とかヒマラヤ山脈があるから南下して中原を侵略するかカザフスタンあたりの遊牧民族を倒してヨーロッパまで行くかしかない、みたいになって割とリアルな遊牧民族の気持ちになれて面白い。次は人とプレイしたら面白いだろうけど、どう考えても沼なのでそこまで行くか迷う。
Tumblr media
2020年は新しくインプットしていきたいこともあるので、ゲームはほどほどにしたいところです。
0 notes
takenos · 5 years
Text
2018年のこと
2018年も充実した年でした。
例によって2019年に入っていますが、思いつくままにまとめていきます。
仕事
1) 入社してからやってきたことの棚卸しをした
2016年の入社から2017年の暮れまで、Wantedly Visit のグロースチームに所属していて、それなりにいろいろなことをやってきた。内容としては大きく二つに分けられる。サービスの改善につながる具体的な施策、とそれを目的としたときのサービスの改善自体の改善だ。後付けだが、構造化するとこんな感じ。
サービスの改善につながる諸施策
タッチポイントの変更 e.g. メール、通知、ディープリンクの設計と対応
インターフェースやインタラクションの変更 e.g. モーダルや検索UI
アルゴリズムの変更 e.g. ランキング、マスターデータ設計
上記の掛け合わせによる機能刷新、及び必要な計測と集計の全て
サービスの改善自体の改善
データ分析の基盤整備 e.g. BigQuery 導入、ジョブシステム実装、BigQuery を叩くための社内専用 Web アプリ
Push 通知の基盤整備と移行 e.g. parse.com の終了に伴う AWS 移行
初期からある API に代わる基盤整備と段階的移行 e.g. リソース指向のライブラリを基礎とした RESTful API のレール整備
内部アーキテクチャの変更 e.g. コアバリューになるべきロジックを切り離して集約、Redis の抽象化層の実装
とまあそんな感じなのだけど、だいたい前者の「サービスの改善につながる諸施策」は話しづらいし、後者はそんなにやって良かったのかすぐに分かるようなものでもないので、あまり話すことがなかった。しかし、少し時間が経ってみて、その後の現象を考察してみると結構やって良かったと思うことも多かった。これらを全部棚卸しした結果、2018年は以下のような内容で3つほど発表をした。
Ruby で作るデータ分析基盤 \- Speaker Deck
Object\-Oriented Abstraction of Redis Sorted Set \- Speaker Deck
Data\-Driven 
Service\-Oriented Architecture & UI \- Speaker Deck
2) 担当するサービスが変わった
2017年の暮れから、Wantedly People という大きくやっているもう一つのサービスの方に移り、バックエンドチームのリーダーをしている。リードという意味だと主に二つの側面があって、1) バックエンドの(主にマイクロサービスに起因する)問題を網羅的に定義したり全体設計を捉えるアーキテクト的な役割、2) バックエンドが一定以上複雑になる場合のサービスの全体設計、という風になると思う。
この二点が自分がやる必要を強く感じた領域で、逆にコーディングやサービス依存性の低いフレームワーク設計のような前のチームで自分がやっていたことの一部は、よりできるメンバーがいるのでやってもらっている。もちろんチームなので他にもマネジメントのこととかもそれなりに勉強しているが、この辺は正直どのくらい成果が出てるのかまだよくわからない。ただ、自分が過去に経験した問題について、ある程度論理的・構造的な解釈ができるようになったのは良かったと思う。
2.1) バックエンドの(主にマイクロサービスに起因する)問題を網羅的に定義したり全体設計を捉えるアーキテクト的な役割
Wantedly People というサービスは Kubernetes をベースとしたマイクロサービス・アーキテクチャを採用している。これは世の中の多くのケースとは違い、組織の問題を解決するというよりは Polyglot ―複数のプログラミング言語を汎用的に扱う― であることを主目的として導入された(ビジネスドメインに合わせてサービスを切るという意味だと、Wantedly Chat という過去のサービスが別のコードベースで動いており、このレベルのドメインでの分割は前提となっていたように思う)。
僕自身は過去に割といろいろな言語を触っているし、ガウディ本でプログラミングを学んだこともあり、問題に適したプログラミングパラダイムや技術を採用するという大枠の考え方には反対ではない。しかし、技術選択による最適化の先行と、新規コードベースでの開発の初速の成功体験から、とにかく切れるところは切る的なアプローチでどんどん新しいサーバーが立っていて、全体としてどう動いてるのかわからないしこの機能どこに追加するのが正しいの…という風になっていて、バックエンドのアーキテクチャを整理することから始めた。以下は、(説明のためかなり簡単化しているが)その結果としてのアウトプットになる。
Microservices on “Rails” \- Wantedly のマイクロサービス事例 \- Speaker Deck
(ちなみに最近出た cookpad さんの記事で似たような失敗談が出てきて、ほんとうにわかる・・・ってなった)
もちろん既存アーキテクチャの把握は始まりに過ぎず、その後、このマイクロサービスは当初想定されていた責務を果たせてないから責務を縮小しようねとか、本来存在すべきドメインが存在していないからしわ寄せが行ってる部分を解消するために新しいマイクロサービスを立てようとか、そういう風に動くことになった。また、より小さいレベルの話として、コアになる体験のドメイン言語をいくつか定義するようなことも必要だった。
当然、もっと純粋に技術的な話もいろいろあって、開発を阻害しない最低限のサービス・ディスカバリや通信の共通化を行ったり、分散システムに起因する各種問題の解決のロードマップを考えたり、会社全体で提供するプラットフォームとしてのアーキテクチャ設計を社内の基盤メンバー(というものができた)と進めたりということもメインのサービス開発の傍ら副業みたいな感じで続けている。
ところで、マイクロサービスというと、どのフェーズで導入するのが会社として適切か、という議論がある���保守的に言えば、モノリシックなコードベースとそれに一致する物理的なサーバー群・デプロイ単位が本当にボトルネックになったとき、という風に言え、したがってマイクロサービスの粒度はチームの数と同じくらい、ということが言えると思う。その一方で、同一のチームのサービスの中でも境界を見出して分割していくということは良い抽象化につながり複雑なシステムの構築を可能にすることや、内部実装における選択の自由を得るというメリットはある。分散システムとしての難しさを克服して導入する価値は、本当にボトルネックが顕在化してどうしようもないという風にならなくとも、あるように感じている。もちろん、そこにいるエンジニアの抽象化のスキルや、インフラ基盤への投資でどこまでレバレッジするかというようなパラメータがあることは言うまでもないけれど。
まあ、言いたかったのは、エンジニア組織が超大規模になって回らなくなったらマイクロサービス必要っていうのは自明だけど、もっと攻めた意思決定もちゃんと考えた上であり得るんじゃないかなと感じているっていうこと。
2.2) バックエンドが一定以上複雑になる場合のサービスの全体設計
サービスを良くするということを考えたとき、当然いろいろなポイントがあって、インタラクションを変えるとか、オンボーディングのやり方を変えるとか、ロジックを変えるとか、はたまた提示するコンセプトを変更するために隅々まで修正を加えるとか、各種ある。
経験的に、モバイルアプリのエンジニアが主導する方が良い変更と、バックエンドが主導する方が良い変更がある。前者は、モバイルエンジニアが必要な API のたたきを作って、それをスマートにバグなく実装できればよいと思う。後者は、バックエンドのドメイン設計やパフォーマンスやアルゴリズムの設計とセットで、自分がサービスの設計に中心的に関わるようにしている。ちなみに、フロントエンドもバックエンドも複雑な場合は、たくさん話し合って協力する。でもそんな技術のキワみたいなものばかり作っていてもサービスの価値が最大化するわけではないので、そういうのはポイントに絞ってやっている。
ドメイン設計というのは本当は別にバックエンドとか関係ないとも思っていて、一言で言えば「我々は何を作りたいのか?」と問い、意味を見つけて、それを何らかの形に落とし込み、他の人にもわかるようにする仕事だと思う。この点、デザイナーは表現技法を多く持っていて、半分くらいはそれに頼るわけだけれども、一定以上扱うエンティティが複雑になりそうな場合は、包括的なデザインドキュメントを自分で書くようにしている。そういったケースでは、ソフトウェアエンジニアリングで培われた抽象概念を扱う技法が活きることが多い(このことから、ドメイン設計は思われている以上に、エンジニアが責任を持つべき仕事であるケースも多いと思う)。
ドメイン設計を行いながら、どのようにサブドメインで分割してサービスを開発できるかを考える。ここでは、おおよそ何と何に分かれるのかが定義する。それができていれば、実際のサービス境界は開発しつつ調整できることも多い。そういう、バックエンドのアーキテクト的なことをしている。
ちなみに、ドメイン設計と言っているけど、新規のサービス開発においては、モデル化すべき対象が現実世界にあらかじめ存在するわけではないし、明確な依頼主がいるわけでもない。ので、DDD本とかで出てくるような、現実を観察して何かをあぶり出していくプロセスだけでは足りない。つまり、ユーザーインタビューを聞いて、ブレインストーミングして、コンセプトが出てきて、UX を決めて、UI が決まって、また戻って、というサービス開発のプロセスを通して、作るもの自体を醸成するということがセットになる。よって、このあたりも含めてやることになった。
サービスを作るという行為は、計算機科学以外にも、グラフィック、インターフェイス、統計、言語、記号、社会、思想、歴史とかいろいろなことへの理解が要求されて、それがとても面白い。2018年は改めてそれを実感した。
生活
買ってよかったもの
クロスバイクっていうちょっとおしゃれな自転車を買った。外に出ることが多くなった。
自転車はカバンじゃないといけないので、ちょっとおしゃれなカバンを買った。いろいろ絶妙で、今ではすごく気に入っている。
ゲーム
スプラトゥーン2を600時間ほどやった。途中でウデマエXというのが導入されたりした。チームを組んで時々対抗戦とかもしてる。一回始めると日が暮れるまでやっちゃうので、見守り Switch というアプリを導入した。このアプリは設定した時間以上やると勝手に Siwtch をスリープしてくれる。本当は子供のゲーム生活をコントロールするためのものだけど、1日中やるみたいなことが起こらなくて便利。
2018年は結構ゲームもやってお酒も呑んだので、2019年はもうちょっと違う方向に振ろうと思う。
0 notes
takenos · 6 years
Text
オブジェクト指向プログラミングにおける Redis Sorted Set の抽象化
(本稿は 技術書展4 にて頒布される WANTEDLY TECH BOOK 4 に掲載される予定の文章です)
はじめに
Redis の Sorted Set を使った一覧画面の実装パターン
Web サービスにおいて Redis の Sorted Set は高速なランキングの実現のためにしばしば用いられる。ランキング・データを Redis に載せることで、高速なデータの取得・ページング・件数計算などが可能になる。ランキングのように順序付けされたコンテンツは Web サービスの一覧画面と呼ばれるページにおいて存在するが、このような画面においてはしばしばリテンションが重要である。レスポンス速度はこのリテンションに対して影響を与えるため、高速な実装が求められる。
一方、時系列で考えた場合、一覧画面の要件はサービスの扱うコンテンツ数が増加するに従って複雑化する。例えば、ユーザーが適切なコンテンツを発見できるようにする必要が出てきて、そのために様々な条件による絞り込みや検索、あるいはパーソナライズされた推薦と言った機能が必要になってくる。
これらの機能をどのように実現したら良いだろうか。通常、絞り込みに使われるようなコンテンツのデータはリレーショナルデータベースに保存されている。一方で、検索の実現には Elasticsearch などの全文検索エンジンが採用されることが多い。また、昨今では機械学習が活用されることも多いが、そのような処理を行うためのライブラリは Python が充実している。このように、ユーザーに価値を提供できる一覧画面に求められる機能は多く、またそれを実装するために最適な技術は必ずしも一つには定まらない。
マイクロサービス・アーキテクチャを採用している場合、各機能を実現するのに最適な技術に基づいたマイクロサービスを実装し、それらを組み合わせることによって一覧画面を実現することが考えられる。しかしこのとき、各マイクロサービスをどのような方法で統合するのかということが課題になる。
既に述べたように Redis の Sorted Set はランキングに利用されることが多いが、和集合・積集合など組み込みの集合演算の命令を使うことで絞り込みや検索、あるいはパーソナライズと言ったより高度な機能を実現することができる。そこで、異なるシステムから集めた情報をそれぞれ別個の Redis の Sorted Set にキャッシュした上で、それを集約計算して一覧画面に必要な情報を算出するような構成を考えることができる。
Tumblr media
この構成では、任意のマイクロサービスやデータベースからの情報をスコア付きの集合とみなした上で統合することができる。また、レスポンスに必要な全てのデータは一度 Redis に乗るため、計算の内容も様々である各システム群がサービスとして求められているレスポンス速度を直接満たさなくても全体として高速に動作すると言った利点もある。
事例
Wantedly Visit では数十万件の募集が存在するが、その一覧画面( https://www.wantedly.com/projects )は上記のような要件を持つ一例である。この画面は実際にこの構成とこれから紹介する RedBlocks を使って実現されている。
実現する上での課題
課題1: オブジェクト指向プログラミングと Redis のコマンド体系のインピーダンス・ミスマッチ
このように Redis の Sorted Set を用いることで一覧画面に必要な機能を実現することができるわけだが、その実装を Redis のコマンドをそのまま呼び出す形で行うと、Ruby などのオブジェクト指向プログラミング言語に於いては高い可読性・変更容易性を実現することができない。
具体的には、Redis のコマンド体系が命令的なものであるため、それをそのまま利用すると手続き的なプログラムになってしまう。この問題は、 単純なキャッシュ目的で Redis を利用しているときには大きく問題にならないが、今回述べたように複雑なシステムを構築する際には問題となる。具体的には、何かアプリケーションの変更を行うときに変更箇所を見つけ出すことが難しかったり、複数の箇所を変更する必要が生じる(変更に対してモジュラでない、関心が分離されていない、と言った状態になる)。
# 非常に単純な集合演算を書くだけでも多くの命令が必要にになる c = Redis.new c.zadd("src1", [[32.0, "a"], [64.0, "b"]]) c.expire("src1", 60) c.zadd("src2", [[44.0, "a"], [21.0, "c"]]) c.expire("src2", 60) c.zinterstore("dest", ["src1", "src2"]) c.expire("dest", 10) c.zrevrange("dest", 0, 5) #=> ["a"] c.zcard("zcard") #=> 1
通常、リレーショナル・データベースをオブジェクト指向の言語から利用する場合、集合指向との概念的な差異(あまり良いメタファーとは言えないが「インピーダンス・ミスマッチ」と呼ぶことがあるので本稿でも用いる)が問題になるため、O/R Mapper による抽象化を行った上で利用することが多い。同様の理由で、Redis の Sorted Set を Ruby から利用する際も OOP に即した形で抽象化を行うことでこの問題を解決することが必要になる。
解消すべき差異の例として、クラスベースの OOP においては、クラスはそれ自体で直接アプリケーションに必要な仕事を果たすわけではなく、インスタンス化を通じてそれを行う。Redis の Sorted Set にクラスとインスタンスのような概念は無いため、key の階層化を通じてこれを実装する必要がある。
課題2: 実装に必要な多くの詳細
実際にサービスで利用するためには概念的な差異以外にも多くの隠蔽できる実装詳細がある。例えば、次のようなことは本来、都度アプリケーションを開発するプログラマが考える必要のないことである。
キャッシュの存在の有無をチェックしてなければデータを取得し Redis に保存する
キャッシュが無い時間が存在しないように差分更新にする
直列依存性のないコマンドのパイプライン実行
Redis の key に使う名前
このような実装詳細を隠蔽することで、アプリケーションを開発する際、
1) サービスの仕様として各マイクロサービスをどう組み合わせるか(AND なのか OR なのか、スコアをどう組み合わせるか)
2) それぞれの計算段階におけるデータをどの程度キャッシュするか
と言った統合に関する仕様(これはサービスの価値に直結する)にプログラマは集中できるようになる。
RedBlocks
具体的に上記のような問題を解決するために、、RedBlocks という Ruby ライブラリ(gem)を用意した。
以降では、RedBlocks を通じてどのように複数のシステムを組み合わせるかを、実際の一覧画面の実装を通じて紹介する。その後、いくつかの実装詳細について言及し、最後にまとめとする。
Case Study: RedBlocks を用いた一覧画面の実装
この章では、課題1として述べたオブジェクト指向プログラミングと Redis のコマンド体系のインピーダンス・ミスマッチがどのように解決できているのかを実例を通して説明する。そのために、次のような一覧画面を想定する。
Tumblr media
この画面には、主に次の4つの機能が備わっている。また、共通する機能として件数表示とページングができる。
ランキング(初期状態)
絞り込み
全文検索
パーソナライズ(ユーザー登録して利用している場合)
これらの機能を順次実装していき、最後にそれをユーザーの操作に応じて行う service クラスを実装する。
1. ランキング
ほぼ全てのサービスにおいて、一覧画面ではコンテンツ(以下、要素)をどのような優先度で表示するのかということを考える必要がある。これはランキングに相当する。全てのユーザーに同じ順番で見せる場合、ランキングを一つだけ用意すれば良い。ランキングは、それぞれの要素に対してスコアが付いた集合、と捉えられるため、Redis の Sorted Set を利用して実装することができる。
ここでは、一覧画面が扱う要素として募集(Project)を想定した上で、カラムとして monthly_page_view を持った Project というActiveRecord モデルがあるするとする。このカラムの値を利用して PV ベースのランキングを作成したい。このための RedBlocks を用いたコードは次のようになる。
class PageViewSet < RedBlocks::UnitSet def cache_time RedBlocks::CachePolicy.hourly end def get Project.pluck(:id, :monthly_page_view) end end
このコードは、まず RedBlocks::UnitSet を継承することで集合(Sorted Set)を表すクラス PageViewSet を定義している。この集合は要素として、月間ページビューをスコアに持った募集含んでいる。
このクラスを利用することで、例えば次のようにランキングの先頭5件を取得できる。
pv_set = PageViewSet.new pv_set.ids #=> [1942, 3921, 354, 1120, 4931] pv_set.size #=> 5121
ids メソッドが呼ばれると、初回は get メソッドの呼び出しを通じて Project クラスからクエリが発行される。その結果は Sorted Set としてキャッシュされた上で、ids メソッドの返り値となる。二回目以降の ids メソッドの呼び出しではキャッシュが利用されるため非常に高速に返る。同様に、全体の件数も size メソッドを通じてキャッシュされた集合から定数時間で取得することができる。 また、ids メソッドに paginator オブジェクトを渡すことで、定数時間でのページネーションも可能になる。実際の Web サービスの実装では、リクエストパラメータとして渡ってきたページ番号をそのまま渡すことが多いと思われる。
このキャッシュをどの程度の期間 Redis 上に保持するかは cache_time メソッドによって決めることが出来る。このメソッドを定義しない場合、キャッシュする時間はゼロとなり、データは Redis 上には最低限の時間しか生存しない(キャッシュしない場合でも Redis 上にデータが生存する必要がある理由は後述する)。
cache_time は鮮度やコストに応じて必要であれば定義すれば良いので、これ以降のサンプルコードでは省略する。
2. 絞り込み
地域の募集の集合 - RedBlocks::Set の利用
サービスのコンテンツが増加してきたことで、募集を地域によって絞り込む機能を提供したくなったとしよう。地域は、「北海道」「東北」「関東」「北陸」「甲信越」「東海」「近畿」「中国」「四国」「九州」「沖縄」の11地域に分類されるとする。このために、まずは地域ごとの募集の集合を表すクラスを定義する。
class RegionSet < RedBlocks::Set def initialize(region) raise ArgumentError unless Project::REGIONS.include?(region) @region = region end def key_suffix @region end def get Project.where(region_cd: @region).pluck(:id) end end
このクラスは次のように具体的な region を引数に与えてインスタンス化することで、先ほどのランキング集合の場合と同様に利用することができる。
set = RegionSet.new('hokkaido') set.ids #=> [1, ... ] # 北海道の募集のリスト
PageViewSet と RegionSet の違いは、PageViewSet は RedBlocks::UnitSet を継承していたのに対して RegionSet は RedBlocks::Set を継承している点と、RegionSet は key_suffix メソッドを実装している点にある。
RegionSet は各地域に対してそれぞれ異なる集合があり得るため、インスタンスとして生成する際に具体的な地域の指定が必要である。更に、Redis に保存する際の保存先も、例えば「北海道地域の募集の集合」と「関東地域の募集の集合」では異なるため、その保存先を指定するための Redis の key の1部分として key_suffix メソッドを実装する必要がある。key_suffix メソッドはインスタンスレベルで異なる集合を区別できるような文字列を返すように実装する必要がある。
一方、最初に紹介した PageViewSet は実質的にクラスにただ一つの集合しか作り得ないシングルトン集合であったため、それに特殊化した RedBlocks::UnitSet を利用した。このクラスはシングルトンを前提としているため、key_suffix メソッドを実装する必要はない。
また、get メソッドの返り値の型に着目してみると、PageViewSet#get は募集の id とスコアのペアのリストを返しているが、RegionSet#get はただ募集の id のリストを返していることが分かる。RedBlocks の get メソッドでは、id のリストを返した場合に内部的に全てスコア0の Sorted Set として扱う。Redis の集合演算ではスコアはデフォルトで同一要素同士で加算されるため、スコアを暗黙的に零元に設定しておくことでスコアに影響を与えない集合として扱うことができる。プログラマは、スコアを持たない(つまり数学的な意味での)集合を利用したいときにはただ要素のリストを返すだけで良い。今回の場合、地域による絞り込み動作は順序には関与しない仕様にしたいため、RegionSet#get はただ要素のリストを返している。
複数の地域に含まれる募集の集合 - RedBlocks::UnionSet の利用
ここまでで特定の地域による絞り込みができるようになったが、「『北海道』または『関東』の募集を探したい」と言ったユーザーのニーズにも応えられるようにしたい(ユーザー・インターフェースとしては、チェックボックスのように複数選択式のものになる)。
これは、集合で言えば北海道の募集と関東の募集の和集合を作ることに相当する。従って、次のような定式化ができる:
[北海道の募集] ∪ [関東の募集]
RedBlocks::UnionSet を使うことで、この和集合演算を実現できる。
region1_set = RegionSet.new('hokkaido') region2_set = RegionSet.new('kanto') regions_set = RedBlocks::UnionSet.new([region1_set, region2_set]) regions_set.ids #=> [921, 324, 21, 39, 101]
公開されている募集のみに絞る - RedBlocks::IntersectionSet の利用
実際のサービスでは、コンテンツには下書き・非公開などの状態が存在し、必ずしもデータベースに登録されている全てのコン���ンツを一覧画面に出せるわけではない。このことを制御するため、次のように公開募集の集合で積集合演算を行った結果を常に返すようにしたい:
[公開されている募集] ∩ ([北海道の募集] ∪ [関東の募集])
RedBlocks::IntersectionSet を使うことで、この積集合演算は実現できる。
visible_set = VisibleSet.new result_set = RedBlocks::IntersectionSet.new([visible_set, regions_set])
さて、公開・非公開などの状態の変更は特にリアルタイムで一覧画面の結果に反映したいものである。そのため、募集の状態の変更に応じて RedBlocks::Set#update! を呼び出して即座にキャッシュを更新するようにする。
class Project < ActiveRecord::Base # ... after_save -> { VisibleSet.new.update! }, if: -> { visibility_changed? && visible? } end
絞り込み結果を PV でソートする
地域による絞り込みを行った結果も、絞り込む前の最初に紹介した PV ランキングに基づいて表示されるようにしたい。これは、最初に作成した PageViewSet を積集合演算に組み込むことで実現できる。
[PageView をスコアに持つ募集] ∩ [公開されている募集] ∩ ([北海道の募集] ∪ [関東の募集])
PageView ではなく最新順で表示すると言ったソート条件の切り替え機能を提供するのであれば、この積集合演算に使うスコア付き集合を変更すれば良い。
[公開日時をスコアに持つ募集] ∩ [公開されている募集] ∩ ([北海道の募集] ∪ [関東の募集])
3. 全文検索
サービスに十分なコンテンツ量と十分多様なユーザーが集まったため、任意のキーワードによる検索機能を入れてより目的の募集に出会いやすくしたい。これまでの計算はリレーショナル・データベースのデータを元にしていたが、今回の機能追加ではよりマッチ度が高い要素から順番にユーザーに表示したいため、全文検索エンジン Elasticsearch へ問い合わせた結果のスコアを採用することにした。
このために特定のキーワードを引数に受け取って Elasticsearch に問い合わせる次のようなモジュールを作成した。Elasticsearch には募集のテキスト情報を同期している。
ProjectSearchService.new("Ruby", format: :id_with_score).perform #=> [[32, 12.1], [811, 11.0], ...]
このモジュールを元に、RegionSet の場合と同様に集合を定義する。RegionSet との違いは、全部検索による該当キーワードへのマッチ度が入ったスコア付きの集合となっている点にある。
class KeywordSet < RedBlocks::Set def initialize(keyword) @keyword = keyword end def key_suffix @keyword end def get ProjectSearchService.new(@keyword, format: :id_with_score).perform end end
この KeywordSet を用いて、例えば次のような集合を構築できればキーワード検索機能を付加することができる。キーワードによるスコアが既に付いているため、ここではPVランキングの集合は利用していない。
// キーワードだけで絞り込む [公開されている募集] ∩ [キーワードで絞り込んだ集合] // 地域とキーワードで同時に絞り込む [公開されている募集] ∩ ([北海道の募集] ∪ [関東の募集]) ∩ [キーワードで絞り込んだ集合]
4. パーソナライズ
ユーザーの行動データが十分に貯まったので、それを元にしてそれぞれのユーザーに合ったコンテンツを推薦したいとしよう。その場合、あるユーザーがそれぞれのコンテンツをどの程度好むのかの予測数値をスコアを持つような集合を定義する。この計算は大規模なログデータにアクセスする他のマイクロサービスが行っている可能性があるが、集合として抽象化できるという点は変わらない。
class PersonalizedSet < RedBlocks::Set def initialize(user_id) @user_id = user_id end def key_suffix @user_id end def get RecommendationService.get_personalized_ranker end end
ここで定義した PersonalizedSet の使い方は色々な可能性がある。ほぼ全ての募集に対してある程度妥当な予測数値が付けられるのであれば単独でスコア付けに利用できるかもしれないし、一部の募集に対してだけ予測数値が付いて他はゼロになっているような疎な集合であれば、0..1 に正規化した上で一般的な人気度をスコアに持つ集合と足し合わせて利用できるかもしれない。念のため定式化すると、次のようになる:
[公開されている募集] ∩ [パーソナライズされたスコアを持つ集合] ∩ (その他の絞り込み条件) // パーソナライズだけ [公開されている募集] ∩ [パーソナライズされたスコアを持つ集合] ∩ [一般的な人気度をスコアに持つ集合] ∩(その他の絞り込み条件)// パーソナライズ + 人気度
5. 全ての統合
ここまで、RedBlocks を用いて定義した集合を組み合わせることで、様々な機能を実現できることを見てきた。実際のサービスでは、これをユーザーの入力に応じて動的に行う必要がある。それを例えば次のような service クラスを作成することで行う。
class ProjectListingService def new(params, user_id: nil) # ... @set = build_set(params, user_id) end def fetch(per: 10, page: 1, format: :ids) paginator = build_paginator(per, page) case format when :ids then set.ids(paginator) when :count then set.size end end private def build_set(params, user_id) sets = params.each do |k,v| ... end sets << VisibleSet.new sets << PersonalizedSet.new(user_id) if user_id RedBlocks::IntersectionSet.new(sets, cache_time: 10.minutes) end end
ここで、新たに RedBlocks::IntersectionSet に cache_time オプションを追加していることに注意しよう。ここまで、RedBlocks::IntersectionSet や RedBlocks::UnionSet と言った合成型の集合についてそれがどの程度の期間キャッシュされるのかについては言及していなかったが、実はデフォルトでは計算に必要な最低限の期間しか生存しない。しかしこのコードでは、絞り込みなどを行った上でのページングが再計算せず高速で行われるように、最終的な出力結果に対しては10分間のキャッシュを行うように設定している。
変更に対するモジュラ性の検討
さて、ここまでで RedBlocks をつかうことで一覧画面をどのように実装するかをおおよそ見ることができた。この実装方法について変更に対するモジュラ性の観点からどのような改善ができたのか、あり得る変更に対してどのように関心を分離できているかを明らかにしておきたい。
同様のロジックを持つ集合をクラスベースでまとめ上げることができる(例:地域クラス - 北海道インスタンス)
これにより、新たな地域を絞り込み項目に追加する際には、それを地域のリストに追加するだけで済むようになる
各サブシステムへのアクセスがクラスの get メソッドに抽象化される
これにより、サブシステムの置き換えと言った変更が get メソッドの実装に局所化されることになる
速度的な最適化は暗黙的なキャッシュにより行われる
これにより、遅いサブシステムにはキャッシュを入れる、と言ったロジックに関係のないコードが省略される
データを引く部分を Set クラス、統合を ProjectListingService で行うという分離ができている
これにより、「言語」と言った全く新しい絞り込み項目を追加する際も他の Set クラスは一切変更せずに済む
具体的には 1) 新規に LanguageSet クラスを定義, 2) Service クラスの変更 の2点を行えば良い
また、各集合のスコアをどのように利用するか、AND にするか OR にするかと言った変更の際は service クラスのみの変更で済む
これは次節で述べるが、Redis に関する様々な詳細実装を省略できる
これにより、本来のアプリケーション・ロジックのみが記述される
このように RedBlocks を適切に用いて実装することで、クラスベースのオブジェクト指向プログラミングの概念を利用して適切に関心を分離した形で、一覧画面を実装できることが分かった。
実装に関する詳細
先ほどの章では、RedBlocks を使うことで Redis をオブジェクト指向の枠組みで取り扱うことができることを説明した。この章では「課題2: 実装に必要な多くの詳細」についてより詳しく述べる。具体的にライブラリが裏で行っている仕事について、以下の6点を取り上げる。
キー体系
キャッシュとして動作させる
Redis 上のデータの生存期間
キャッシュを差分更新にする
空集合を表現する
集合の最適化
ここでは実装上の詳細について取り上げるため、特に全体としてまとまりがあるわけではない。興味のある話題だけを選択的に見てもらえれば幸いである。
キー体系
Redis を利用するには当然キーを指定する必要があるわけだが、このキーについて RedBlocks では次のような体系を用いている:
<全体の名前空間>:<クラスレベルの識別子>:<インスタンスレベルの識別子>
まずキーが3階層に分けれている。最初の階層は全体の名前空間を表していて、デフォルトで "RB" となる。二つ目の階層はクラスレベルの識別子を表していて、RedBlocks::Set を継承したクラスの名前がデフォルトで利用される。三つ目の階層はインスタンスレベルの識別子を表していて、主に key_suffix メソッドの実装を通じてプログラマが指定する。例えば、先ほど出てきた「北海道」地域にある募集の集合、次のようなキーが構築される。
r = RegionSet.new('hokkaido') r.key #=> "RB:RegionSet:hokkaido"
合成型の集合のキー
RedBlocks::UnionSet など合成型の集合の場合は、key_suffix の決定を自動で行う。ルールは、内包する全ての集合のキーをソートして | によって結合したものとなる。
r1 = RegionSet.new('hokkaido') r2 = RegionSet.new('kanto') RedBlocks::UnionSet.new([r1, r2]).key_suffix #=> "[RB:RegionSet:hokkaido|RB:RegionSet:kanto]" RedBlocks::UnionSet.new([r1, r2]).key #=> "RB:RedBlocks::UnionSet:[RB:RegionSet:hokkaido|RB:RegionSet:kanto]"
これによって、カスタムクラスを定義することなく簡単に和集合や積集合と言った合成集合を作ることができている。
キャッシュとして動作させる
キャッシュとして動作させる、つまり「無ければ元データを取得しキャッシュに乗せて次回以降はそれを使う」という動作を実現するために、次のようにデータ取得の際にキャッシュの有無をチェックしている。
module RedBlocks class Set def disabled? RedBlocks.client.ttl(key) < RedBlocks.config.intermediate_set_lifetime # この lifetime はデフォルトで30秒 end def ids(...) update! if disabled? ... end end end
このコードは、該当のインスタンスに相当する Redis の Sorted Set の生存期間がまだ30秒以上あれば有効であり、そうでなければ無効と判定してデータの更新を行っている(0ではなく30秒である理由は次で説明する)。
Redis 上のデータの生存期間
RedBlocks を通じて利用する Sorted Set はキャッシュとして一定期間 Redis 上に存在させることができるが、その一方で ZINTERSTORE(dest, src1, src2, ...) や ZUNIONSTORE(dest, src1, src2, ...) と言った演算を Redis 上で行うためには、キャッシュ期間をゼロに設定されている(つまり結果を返した直後に消滅して良い) Sorted Set であっても最低限存在しなければならない期間が存在する。
RedBlocks ではこれをデフォルトで30秒と定め、「(get メソッドを通じたデータの取得も含めて)ids を呼び出してから最終結果取得までの全ての工程が30秒以内に終了する」という仮定の元に正常に動作することを保証している。
以下に示す実装の通り、キャッシュとして存在する時間とは別で30秒は必ず存在するように全ての生存期間が設定されている。
module RedBlocks class Set def expiration_time RedBlocks.config.intermediate_set_lifetime + cache_time end def update! ... RedBlocks.client.expire(key, expiration_time) end end end
キャッシュを差分更新にする
キャッシュの更新の際、一度全てを削除してから新しくデータを入れるという方法だと、瞬間的にサービスにおけるコンテンツの件数がゼロになってしまう。一瞬であってもその状況は好ましくないため、実際のキャッシュの更新処理では更新の前後で���除された要素のみを明示的に Sorted Set から取り除いている(増分に関してはスコアのみが変わる可能性もあるため、全てを更新する必要がある)。
module RedBlocks class Set def update! ... RedBlocks.client.pipelined do RedBlocks.client.zrem(key, removed_ids) if removed_ids.size > 0 RedBlocks.client.zadd(key, all_entries) RedBlocks.client.expire(key, expiration_time) end end end end
空集合を表現する
Redis の Sorted Set の仕様では、内包する要素が0件であるという状態と、Sorted Set 自体が存在しないという状態を区別できない。しかし、RedBlocks のユースケースにおいては、「空の集合である」という状態もキャッシュしたい(例えば、特定のキーワードによる全文検索の結果が0であるということ自体もキャッシュしたい)。
このため、実際にコンテンツに対応する要素以外に、id が 0 の要素を常に加えるようになっている。この 0 は実在する要素の id として取り得ない値を想定しており、RedBlocks.config.blank_id を通じて別の値にも設定することができる。
集合の最適化
最後に、集合構造を最適化する RedBlocks::Set#unset について紹介する。
状況として、「職種」と「地域」と言った複数の観点での絞り込みができる仕様があるとする。例えば、次のようなクエリがあり得る:
# pattern 1 ([エンジニアの募集] ∪ [デザイナーの募集]) ∩ ([北海道の募集] ∪ [関東の募集] ∪ [東海の募集]) // pattern 2 [デザイナーの募集] ∩ [北海道の募集]
このとき、両者を同時に処理できるように一般的なプログラムを書くと、後者は次のような構造になる可能性が高い。
pattern1_set = RedBlocks::IntersectionSet.new(RedBlocks::UnionSet.new([engineer_set, designer_set]), RedBlocks::UnionSet.new([hokkaido_set, kanto_set, tokai_set])) pattern2_set = RedBlocks::IntersectionSet.new(RedBlocks::UnionSet.new([engineer_set]), RedBlocks::UnionSet.new([hokkaido_set]))
当然ながらこの集合構造は冗長であり、最初に示したようなクエリに変換できると良い。形式的に言って内部に1つの集合を持つような積集合はその内部の集合と等価であるため、このような冗長な構造を再帰的に最適化するために unset メソッドを用意している。この例では、以下のように動作する。
pattern2_set.unset #=> RedBlocks::IntersectionSet.new(engineer_set, hokkaido_set)
制限事項
以上、この節で紹介した実装詳細のうち、次の二つのアイデアについて制限事項を検討する。
Redis を演算とキャッシュの二つの目的で利用
Redis のキーの自動生成
1 により単純なシステム構成になり、2によりプログラミング上の些事が消失する。 これがクイックに低レイテンシーな検索・フィルタリングシステムを構築することに寄与する。 しかしながら、いくつかの状況においてはこのアプローチは適さないと思われる。
まず1については、Redis 上での演算を前提としているため、演算性能もまた Redis の上限に制約される。これは数十万件程度のデータが対象であば問題にならないが、数千万件以上のデータがある場合は性能上の問題が出る。このような規模に成長した場合は、演算の責務を Redis に担わせるのではなく別のシステムに担わせるのが妥当だろう。
次に2については、クラス名というプログラム上の実体からキーを生成しているため、それの変更に影響を受ける。これがキャッシュの Thundering Herd を引き起こす可能性が原理的に存在する。そのような非常に高並列性のシステムにおいては、演算をオンラインで行うのではなく、オフラインで行っておくなど、異なるアプローチを検討するべきだと思われる。
おわりに
本稿では、Redis の Sorted Set の Web サービスにおける活用方法として、一覧画面の実装での利用を挙げた。特に、マイクロサービス文脈では複数のシステムの「統合」に課題があることを指摘し、その基幹部分に Redis の Sorted Set を使うことを提案した。
その上で、それを現実的に保守可能な形で実装するために RedBlocks という抽象化を行い、実際のアプリケーションで求められる仕様をピックアップしながらそれを上手く記述できることのケーススタディを行った。このケーススタディの中では、HTTP サーバーではなく ActiveRecord を介してデータベースへ問い合わせるようなサンプルコードも掲載しているが、マイクロサービスの移行期には HTTP による通信とデータベースへの直接参照が混合するケースも多く、そういった部分も含めて現実的に使っている統合手法として紹介した。
また、RedBlocks については更に踏み込んで、アプリケーションのロジックを完結に記述できるようにするために裏にどのような仕事を隠蔽する必要があったかを紹介した。特に、複雑な Redis のデータ構造をどのようにクラスベースのオブジェクト指向プログラミングに落とし込むか、それと関連してどのようにシステマチックにキーを管理するかというようなトピックは、他の Redis のデータ型に対しても適用できる可能性もあり、今後の発展が見込める。
0 notes
takenos · 6 years
Text
2017年のこと
もう2018年に入ってしまったけど、簡単にまとめておく。2017年は凄い発見みたいなのはなかったんだけど、色々積んだ結果見えてきたものも多かったのでまあ良い年だったと思う。
仕事
去年に引き続き Wantedly Visit というサービスの開発をやった。アプリケーションのコード書いてる時間が4割、基盤の開発が2割、データの分析が2割、とかそんな感じ。まあこの辺の時間の使い方はあんまり変わっていなくて、変わったことと言えば、アーキテクチャ・レベルでのやり方を決めたり変更したりといったことをかなり意識的にやるようになった。これは単純に技術的にそれまでより色々な可能性を考えるようになったというのもあるけれど、サービスとして本質的に強くしていくべきところはどこかを考えていった結果そういう結論になるということでもあった。
それと関連する話で、サービスを作るにあたってデザイナーと密にやることが増えて、学生時代にサービスデザインだとか言語学・記号論とか色々首を突っ込んで理解していたことが普通に思考や会話の役に立っていて、そういう意味では楽しい一年間だった。
技術的な話
技術的な話を少しすると、2017年は “人と会社のマッチング” という風に自分の取り組むテーマを置いてやった結果、フロントエンドからバックエンドまで幅が拡がったのが良かった。具体的には会社に出会うための UI を最適化する過程で複雑な状態制御のために React を画面に入れたり、ちゃんとした検索が出来るように ElasticSearch を入れたりといったことがやりたいことから自然に生まれた。全文検索以外の部分はリレーショナルデータベースでやる方が簡単なので、高速化も兼ねて Redis の Sorted Set をかませてシステムを合成している。Redis の Sorted Set は素の状態で複雑な使い方をすると可読性や変更のモジュラリティが著しく下がるので、 ActiveRecord のように OOP のスタイルで扱えるような抽象化層を用意した。このあたりのことは機会があればちゃんと記事を書きたい。
推薦システムというものは突き詰めて行動データを使って最適化していくのが一つの有力な手法になる(別のやり方としてコンテンツデータを元にしたものもある)。類似する会社を推薦するために協調フィルタリングを入れたのだけど、これは割と素直な結果を出してくれてそのまま投入できた。また、ある時はバックエンドに Python サーバーを追加して簡単な強化学習を行うようにしたけど、これは意外と上手く行かなかった。このときは学習は正しく行われたのだけど目的自体は達成できないというもので、対象に合わせたモデルを作る能力の必要性を感じた。
あと基盤的な話では、この辺のことを全部やるためのデータ分析基盤みたいなものは必要に応じてちょくちょく作っている。このことは会社のブログに書いた。またそのサービスのネイティブアプリの API を書くのも仕事のうちなのだけど、色々な歴史的経緯でそれの生産性がやばかったので少しシステム化された RESTful APIを導入した。これもブログに書いた。これら二つは具体的な課題意識があってやったことではあるけど、それを下地に抽象的な思考に基づいて ”一般的にこういうものが必要だろう” という風に作った結果、当初見えていたよりも大きな結果を得ることが出来た(前者は組織を超えて全社的に使われるという形、後者は利用者の生産性が想定を超えて上がるという形で)。こういう経験はエンジニアリングに限らず得難いものだなと思っていて、非自明であってもその時やるべきだと感じたことは大事にしたい。
まとめると、一つのテーマを追求して基盤から UI、プログラミングから検索・機械学習まで必要に応じてやって、概ね成果が出たのは良かった。あと、このチームはインターン時代含めると3年近くいたことになるけど、2018年から全く新しいチームでやることにした。これまでより更に意義のある仕事ができると良いなあと思っている。
ガジェット
2016年に生活の劇的に向上させたのは引っ越しだったけど、2017年は iPhone X だった。漸進的な改善にお金は払わないぞという謎の意志の元、半分くらい壊れてる iPhone 5S を使い続けていたので、まともに使える iPhone が手に入ったという要素が大きい。1Password(Face ID), Wallet, Spotify, Moneyfoward, Kyash, Swarm, OPENREC.tv, DMM Okan. などは新しく入れて便利に使っていて、色んな意味で感覚が追いついた感がある。
あと電子機器関係だと Airpods とか Google Home とか HHKB Bluetooth あたりは買って普通に良かった。
ゲーム
Splatoon をやるために発売日に Switch を買った。社会人になって学生の時よりも時間が取れなくて厳しい。でもチームでやる対抗戦は楽しいし、OPENREC.tv とか良いサービスも出てきて、それでプロ・ゲーマーが生まれたりと界隈も盛り上がっていて、本当に上を目指すとかは出来ていないけどそれでも楽しい。
学生時代にゲーム動画のサービスとか作って個人で色々工夫していたけれど、Switch / Splatoon 2 はプラットフォーマー側でも然るべき種蒔きが行われていて、それが OPENREC や Twitter などの周辺のシステムと連動して盛り上がっていて、おおついにここまで来たか…!という気持ちになった。
ちなみにゼルダの伝説もまあまあ面白かったのだけど、僕としては対コンピュータはそろそろエネミーが強化学習とかで強くなる世界を期待していたので、ハードモードが追加されたときに単純にエネミーの HP が増えただけだったのはちょっと残念だった。
Switch / Splatoon 2 は多対多のゲームでやって欲しいと思っていたものが見れたのがとても良かった。対コンピュータというところでも、そろそろ新しいものが見たいなと思っている。
物語
元々これに当てていた時間を2017年はゲームに振ったので殆ど積めなかった。。いくつか映画観たのと、SAO のアリシゼーション編全10巻を読んだくらいしか記憶になくて、あんまり私的にセンセーショナルな出来事もなかった。
.
2017年、それなりに良い年ではあったけどもうちょっとやれるなあと思う部分もあるので、2018年はもっと面白くしていきたいなと思う。
0 notes
takenos · 7 years
Text
2016年を振り返る
年末の振り返り、毎年やっている途中に年が明けてしまうのですが、学生生活が終わって、これからの一年一年は積み重ねていくのが大事だと思うので、完成させておきます。
2016年の出来事は大きなところで4つくらいありました。それぞれについて思うことを書いていこうと思います。
大学生活の終わり
西ヨーロッパを旅行する
会社に入る
引っ越した
大学生活の終わり
もう結構前のことに感じますが、修士まで含め6年間を過ごした大学生活が終わりました。やりたいことをやった大学生活だったなあと感じます。少し振り返ってみたいと思います。
実は大学に入る前は機械か情報のどちらかをやりたいと思っていて、受験は機械 -> 情報 の順番でとりあえず志望したのですが、点数の関係で情報系に入ることになりました。それなら両方やってみようと思って、ロボット技術研究会(ロ技研)というサークルで機械・電子工作をやりました。実際に動くものが出来るのは純粋に楽しかったのですが、ハードウェアを扱っていくことで逆にソフトウェアの技術の特徴を認識することにもなりました。例えば、簡単なロボットを作成するのにしても、アルミ材や電子部品、足りない場合は適宜調達、調達後は旋盤・フライスで加工、と言った工程が必要になります。工作好きとしては楽しいものでしたが、高校時代に経験した、ソフトウェア(ゲーム)を作ってインターネットを通して友達に使ってもらった経験からすると、自分がやりたいのはそちらではないと感じました。この点は、ジョナサン・ジットレイという人の書いた “The Future of The Internet”(邦題:『インターネットが死ぬ日』)という本でより構造的に説明されています。汎用性に加えて伝搬性や習熟性など、いくつかの条件が揃った道具は、それ自体から新しいものを生み出す肥沃な(generativeな)システムとして機能する、というような議論です。
Tumblr media
インターネットが死ぬ日 (ハヤカワ新書juice)
ジョナサン・ジットレイン 早川書房
もうひとつ、大学の研究室を取材して学部生に説明するメディアを発行している団体にも所属していました。理工系という枠の中ではあるけれど、特定の分野に依らない環境というのは当時は貴重で、ここで人と話したことがあとあとの科学全体への理解に役に立った気がします。
そういった学生団体以外のところでは、プログラミングの本を読んだり、バイトをしたりしながらふらふらやっていました。今では手に入りにくいみたいですが、『コンピュータプログラミングの概念・技法・モデル』という分厚い本を時間をかけて読んだのが良い思い出です。
Tumblr media
コンピュータプログラミングの概念・技法・モデル (IT Architects' Archiveクラシックモダン・コンピューティング)
セイフ・ハリディ ピーター・ヴァン・ロイ Peter Van-Roy Seif Haridi 翔泳社
この本はその名の通りプログラミングの本なのですが、プログラミングを統合的な学問として教えるのはどうすればいいか?ということを意識して書かれたもので、いま思うと非常にビジョンに溢れた仕事でした。この本を読むことで、状態(state)や並行(concurrency)といったソフトウェア概念への正確な理解から、そもそも抽象化とは何か?という根本的な話まで、知ることができました。
抽象を設計することは必ずしも容易ではない。いろいろな考え方を試し、破棄し、改良し、といった長くつらい道のりになることがある。しかし、その見返りは非常に大きい。文明はよくできた抽象の上に建立される、といっても過言ではない。毎日、新しい抽象が設計されている。車輪やアーチといった古代の抽象のいくつかはいまに残っている。セル電話のような新しい抽象のいくつかは速やかに現代の日常生活の一部になった。
良い本を読むたびにいつも思うのですが、その本の射程距離と言うか、書き手が読み手をどこまで連れて行ってくれるかは、ほとんどの場合、序文を読めば鋭敏に分わかります。最初の問いかけが、問題意識が、その可能性としての範囲を決めている。
そういえば、ずっと昔、高校生のときに読んだこの記事なんかは、そういう思考の"強度"みたいなものの存在を知った最初のものでした。
ネットに時間を使いすぎると人生が破壊される。人生を根底から豊かで納得のいくものにしてくれる良書25冊を紹介 - 分裂勘違い君劇場
これは自分の話ですが、技術を手に入れると、最初、何かを作れるということ自体に喜びを見出します。しかし、少し考えてみれば、世の中には、素晴らしいと思うモノもあれば、そうでもないと感じるモノもある。
それを分ける違いってなんだろう?「価値」って何だろう?「意味」ってどうやって生まれるんだろう?…実はそういうことを抜きにして技術だけを持っていても、真に納得のあることってできないんじゃないか――もしかしたら専門特化で市場価値だけは手に入れられるかもしれないけど、それは現代において幸せとは関係が薄い――、そういうようなことを思ったのが大学生活の中頃だったように思います。
それからは、デザインみたいなものづくりに近いところから始まり、思想、 言語、社会みたいな、かつて興味を感じていたけど離れていたものに触れたり、あるいはゲーム、エンターテイメントを好きなだけ体験しました。そして今では、そこで得たもの抜きで何かを思考することは考えられないくらいに、世界の見え方が質的に変わりました。
Tumblr media
ソシュール 一般言語学講義: コンスタンタンのノート
フェルディナン・ド ソシュール 東京大学出版会
例えば、自分の使っている身近なサービスであっても、それを単に機能と見なすのか、大きなマクロの流れを見据えた人間の行動と見るのかで、感じられる価値って圧倒的に違ってきますが、これってその周辺に対する文脈的・構造的な理解なしには得られないものです。同様に、エンターテイメントを咀嚼していけば、小さなできごとにものすごく大きな意味がありそれが面白さに深く関わっている���とが分かるし、ゲームは、最近よく描かれるように、「仮想的」なものに内的な意味が生まれてそれが「現実」への問い掛けとして機能します。
先に紹介した、良い本や物語が人生を豊かにするという高校時代に出会ったイデオロギーは、こうして自分の中で消化されていきました。
1990年代から2010年代までの物語類型の変遷~「本当の自分」が承認されない自意識の脆弱さを抱えて、どこまでも「逃げていく」というのはどういうことなのか? - 物語三昧~できればより深く物語を楽しむために
実を言うと、「専門」外の方向に向かった背景として、ここで書いた以外にも、理工系の大学にいてそこで用いられる枠組みに、それだけでいいのか?という感覚や、枠組みを用いるときにその特性を理解しておきたいということもあったと思います。ただそれは経緯というかきっかけであって、今もそういったものに価値を感じるのは、単純にそれが豊かだという以上の理由はないです。
西ヨーロッパを旅行する
大学生活最後の春休みには、イギリス・フランス・ドイツの西ヨーロッパ地域を一ヶ月ほど一人で旅しました。大きく時間を取れることもしばらくないからというよくある考えですが、この地域を旅行先に選んだのは、前述のような思考履歴を辿った自分にとっては、ごく自然な流れでした。
現代から遡る形で勉強していくと、いかに多くのものがこの地域世界から流れてきているかということを痛感します。日本だと、明治以降、いわゆる近代化ですが、そのことは、渡辺京二の『行きし世の面影』を読んでより強く自覚しました。この本は幕末-明治に日本を訪れた西洋人の記述を集めて、在りし日の「ある文明」を描写したものなのですが、読んでみて驚くのは、その世界を現代に生きる僕は、その時代の日本人ではなく日本を訪れた当時の西洋人の視点から(!)解釈・理解してしまうことなんですね。それほどまでに異なる秩序を持った生活世界がかつてあり、それがある時代を区切りに全く別の存在になったことを以って著者は「文明が滅んだ」と言っているわけですが、ともかく、現代日本がその多くを西洋近代文明に負っているということをまざまざと認識されられた本でした。
Tumblr media
逝きし世の面影 (平凡社ライブラリー)
渡辺 京二 平凡社
話を戻すと、旅行はイギリス・ロンドンから始めてイングランドの地方を周りつつ、フランス・パリに移動。そこからドイツのバイエルン地方をいくつか街を経由しつつミュンヘンまで行きました。
月並みな感想ですが、実際に行って見て理解できるものって、全然、本とかで読むのと違いますね。イギリスとフランスの違いとか、歴史を知れば文脈的な立ち位置とか理解できますけど、行ってみるまで感覚として理解できてなかったなと思いました。ロンドンからパリに移動して一歩街に足を踏み入れただけで、一日街を回っただけで、こんなに違うのかと感じました。こういうことは総体としてそう感じるものなので、短く言葉にするのが難しいところはありますけど、例えばロンドンの街では英語が基本で、なんと言うか、国際都市としては純度が高く感じました。それがパリに踏み入れるとあらゆる言語が入り混じっている。あるいはミュンヘンの酒場に行けばスイス人やイタリア人が出張で来ていたりする。自分は子供の頃インドネシアに住んでいたこともありますが、考えてみればそれも島国で、実はこれまで「大陸」に行ったことがなかったので、普通に外国人がちょっと移動して来るみたいなのは感覚としてありませんでした。その点一つとってもイギリスの立ち位置って違うなと思いましたし、ちょうど返ってきて少し後で Brexit がありましたけど、それまで積み重ねられてきたヨーロッパ統合の流れの転換点になる出来事でやはり衝撃を受けつつも、納得するところもありました。
Tumblr media
イギリス 繁栄のあとさき (講談社学術文庫)
川北 稔 講談社
Tumblr media
フランス史10講 (岩波新書)
柴田 三千雄 岩波書店
Tumblr media
ドイツ史10講 (岩波新書)
坂井 栄八郎 岩波書店
こうやって実際に行ってみるとその後もより色々な出来事を面白く感じるようになったので、またどこか行きたいなあ。
あと、宿泊は全て Airbnb で行いましたが、これは旅行体験を別の次元に引き上げてくれる、本当に素晴らしいサービスだと思いました。機会があればちゃんと書きたいところですが、現代みたいに世界が近づきつつある(と思っていたら2016年はそれに逆行する出来事が象徴的な年になりましたが)時代って当然文化的なコンフリクトも色々起こるとおもうのですが、それを暮らしというミクロなレベルから地道に解決していくアプローチは、プラクティカルではあるけど妥協の無いもので、僕はとても好きになりました。
Wantedly に入社する
4月になって、本格的に働くときが来ました。働く先は Wantedly という会社に決めていました。会社選び、かなり多くのパラメータを使って決めていて、自分が考慮したなと意識したものでも普通に50個くらいはある気がするんだけど、ざっくり言うと、エンジニアリング・カルチャー・ビジョンの3点で良いと思ったと言えば近い気がする。
ここでビジョンについてだけ言及すると、熱中して仕事に取り組むような人を世の中に増やす、という目的でやっています。僕はこれを見たとき、ああ、これって今やることに意味があることだ、と思いました。
これは結構早い段階で思っていたことですが、正直、今の世の中食べていくだけですごい困ることはなくて、娯楽もインターネットにつなぐだけでコンテンツに困ることもない��すよね。これって結構すごいことだと思ってて、また、同時に新しい問題を生むとも思います。
過去を振り返れば、戦後とか食べることがリアルに重要な問題であるときもありました。その後の高度経済成長の時代も、結構「物」を手に入れるということに価値を感じていた時代だと思ってます。「機能」にお金を払うことが多かった、と言ってもいいかもしれない。
実際問題として、平均的な大衆のために開発された、どれも悪くはないが実のところ本当には自分にフィットしていない商品群に出会うのが、二十世紀の商品棚の典型となる - x-DESIGN
一方、当時、僕が iPhone を買うとき、何に対してお金を払っているんだろう?と考えたとき、純粋に何かが出来るということ以上に、新しい何かを見せてくれるのではないかという「期待」や、製品のディテールにこだわるという彼らの行動様式への「共感」に対して払っている部分が大きい、と感じていました。そして、そういう行動は自分以外にも普遍的に見られるように思えたし、エンターテイメントもこの傾向を反映しているように見える。
この考えを仕事というものに敷衍していくと、近代以来の時間を対価とした労働観念も、少しずつ変わっていくのかなと思いました。そして、そこではいくつかの選択肢があるべきで、その中の一つとして、仕事って面白い、と思ってそこに金銭的対価以上のものを見いだせるという選択肢が用意されるべきだと感じていました。ここで少し強い言葉を使っているのは、当時、もしかしたらその選択肢があれば選んだかもしれないけれど、無いがために選ばなかったと感じた事例を見たからでした。
なんか、色々話を聞いていると「退却」してしまう人が多いなと感じていて、それはそれで戦略としては正解なんだと思うんだけど、やっぱりどこか残念だと思うよね。
もちろん、趣味に生きるのはすごくありだと思ってて。自分自身、しばしばそっちに振っていたし、それで最後まで楽しそうにしていた人というのも知っている。
なのだけど、それはナチュラルにそうであったという場合であって、「退却」するケースというのは、だいたい最初に希望があって、それを全うできない「疲れ」がそうさせたみたいなストーリーになっている。
趣味に生きるのは良いけど、趣味に生きざる負えないみたいなのは、残念だ。
残念な事象が類型化されると、そういう風になってしまうシステムが残念だという思いに至る。だから、ここで言う残念というのは、人ではなくて構造に向かっている。
構造と言っても色々なレイヤーで見ることができて。
いちばんは、そういう事象が生み出されるのが、構造と要素のミスマッチによるものであるということ。
そして、そういうミスマッチが生み出されるような構造によるものだということ。
さらに、それを生み出す構造が維持され生き残るような、文化によるもの。
…何やら話が少し重くなってしまいました��、そういう経緯もあり、仕事自体はかなり楽しんでやっています。個別の内容については今は振り返るほど過去にはなっていないので、このあたりにしておきますが。
引っ越した
2016年後半の個人的にエポックメイキングな出来事は引っ越しでした。大学のある大岡山から、会社のある白金台へ。2ヶ月前に出来た家賃補助制度を活用して、1ヶ月前に出来た部屋に引っ越しました。会社まで徒歩1分のところにあり、めちゃくちゃ落ち着いている。
Tumblr media
住居、何を求めるかだと思っていて、「寝る」という機能だけを求めるのか、「生活する」基盤にするのかで違ってくるというのがありました。
大学時代の部屋は正直そんなに居たいと思えるような部屋ではなくて、それは採光や諸々のデザインの制約で変えられないと思っていて、ただそれでずっと不満はなかった。なかったのだけれど、「生活する」というのをしっかりやると、そこで感覚のチューニングもできるようになるし、意外と大事だなーというように考えを変え、ここには投資しました。結果的には、驚くほど生活の質が上がったので、これは完全に正解だったなあと思います。
ここでは備忘も兼ねて、引っ越しの際に考えたことを4つくらい上げておきます。
ポテンシャルのある部屋を選ぶ
まず、経験的に、部屋は、生活の質の上限を決める。これが部屋の定理。
そもそも綺麗でないと綺麗に保つ気にならないという意味で、きれいである必要があるし、ベースとなるデザインが良くないと結構どうしようもない。窓やそこから見える景色は変えられないので超重要。また、キッチンが部屋と分離されていると使わないという自分の経験則があったので、インテグレートされているのが望ましい。また、広さはそんなに必要ないことも分かっていて、それ以外を優先する。
徹底的な断捨離
ネットで見つかるきれいな部屋の隠れた法則として、そもそもものが少ない、というのがある。
このため、3週間くらいかけて、本当に自分に必要なものとそうでないものを選んで、処分・売却していった。この結果8割くらいのものを処分することになり、引っ越し先でもものが溢れずに済んでいる。
とは言っても、思い出のもので捨てづらいとかもある。そういうものはひとしきり懐かしんだあと、写真を撮って送り出す。ありがとう。
生活サイクルの再設計
おそらく超基本的なことなんだけど、掃除、洗濯、食事をまともにやれていなくて部屋がゴミのようだった。それもあって部屋にいる時間がゼロに近いかたちで運用していた。次の部屋でそうならないように、適切なタイミングの設定と、それを行うコストを下げるように色々導入した。
これはちゃんと成功していて、今は部屋は綺麗に保たれていて、洗濯も定期的に行っていて、とても精神衛生が良くなった。
生活空間の再設計
部屋は広くはないので、そもそもの部屋でやることを絞るというのも重要だった。会社が近いので本格的な事務作業は全て切り捨て、平日の寝ることと、休日の食事しながら本を読んだり映画を見たりすることにフォーカスした。本とエンターテイメントがあれば幸せに生きていける。
基本的な知識がないと良いものはできないので、インテリアの本を一冊買った。インテリア本、イケてる部屋の例みたいなのを載せてるだけのものが多くて微妙な感じだったけど、マンション・インテリアに特化したものを見つけて買った。
Tumblr media
ライフスタイルを生かす マンション・インテリアの基本
新星出版社 (2016-07-01)
その他、集約する方向ばかりだと面白くならないので、事前に Pinterest で良さそうなものを集めてイメージをふくらませたり、インターネットで色々面白そうな部屋の使い方を仕入れたりという感じで、引っ越しプロジェクトは大変だったけど結構楽しかったです。
おまけ:2016年個人的エンターテイメント史
2016年の後半はやはり映画が熱かった
『シン・ゴジラ』『この世界の片隅に』『君の名は。』『聲の形』は残ってる
ラノベは好きなタイトルが軒並み続編が出なくてかなしい
『ログ・ホライズン』『やはり俺の青春ラブコメはまちがっている。』
マンガはまずまず順調
2017年はそろそろ『ヒストリエ』10巻が出ることを期待
2017年について少し
今年について簡単に思ってることを書いておきたいと思います。
まず、仕事の面は、ちゃんとコミットすることでこそ得られるものがあるというのが自分の中で実証されました。今しばらくこのままいろいろ積んでいきましょうという感じです。
あと、これは意図的にそうしていた面もあるのだけど、2016年の4月以降はほとんど本を読んでいなくて、これはそろそろ変えたいなと思っています。いま振り返ってみても、色々なポイントでの判断にそこの積み重ねが活きているのはやっぱり間違いないので。
その他、生活面では、もっとエンターテイメントを消費していくこと、本格的に料理を始めること、 プロジェクタを買いたい、とか色々ありますけど、まあここはなるようになれという感じですね。
そんな感じで2017年もよろしくお願いします。
1 note · View note
takenos · 8 years
Text
フランス史メモ
フランス滞在初日。安定のスタバで『フランス史10講』を半分ほど読んで過ごしました。太陽王・ルイ14世のところまで。
Tumblr media
フランス史10講 (岩波新書)
柴田 三千雄 岩波書店
歴史、割と子供の頃に習慣のように読んでいて、この本に出てくるような出来事は知識としては一通り知っているのだけど、きちんと意味付けができていたかったので今まで時系列的な前後関係や空間的な位置関係がバラバラだった。それが、一本通すように全て繋がっていく様はとても快適で、一方でもっと早くに気付けなかったものかとも思ったり。
特に今回の旅行に関係する部分だと、イギリス、フランス、ドイツの違いに焦点が当たる。一つは、ドイツの都市についてで、旅行するには当然目的地を設定する必要があるんだけど、ガイドブックとか眺めててもいまいち決まらなかった、、。例えばフランスならパリ、イギリスならロンドンってあるわけで、それがドイツだとどこなの?と言うといまいちよく分からない。もちろん、単一の都市に全てを集約するのではなくて、例えばニューヨークとワシントンみたいに商業的な都市と政治的な都市が分離されているパターンはあるけれど、これは機能の分離が地理的な分離として現れたわけで、まあ分かる。でも���ドイツはなんかそんな感じもしない。文化や商業あるいは政治のどちらでも単一の中心点が定まらない。一体どうなってるんだろう?って思ってたけど、この本を読んで分かったのは、フランスとドイツは途中までは同じ道をたどっていたけど(前エントリ参照)、フランスはカペー朝というのがパリ周辺の地域から現れて強力な王権を確立していくのに対して、ドイツは伝統的に領邦君主が色んなところにいて、それが皇帝を選ぶのがずーっと続いていたので、元々分散的だったんですね。特に、日本であんまりこういうモデルはないので、この話を読むまで理解できませんでした。
もう一つは近世のイギリスとフランスの政治形態の違い。この辺の王権に対する考え方ってすごく面白くて、王は基本的に色々命令する権利があるのだけど、その正当性は「聖別」によっていて、従って神意に沿った、すなわち国民の幸福に資するような決定を行なわなければいけないというのがある。このような前提があるときに、臣下は王の決定を拒否できるのか?という問いを立てると、これは王の正当性に照らし合わせると意外に自明ではない。ここにグラデーションがあって、王の権力を非常に大きく認めたのがフランス的な絶対王政で、法をもって王の権力を制限した形がイギリスの議会政治だったという話を聞いて、それまで根本的に違うものだと思っていたので、すごく納得しました。
Tumblr media
0 notes
takenos · 9 years
Text
「当たり前」を超えたい
お正月、実家でフェルディナンド・ソシュールの『一般言語学講義』を受けた。
ソシュール 一般言語学講義: コンスタンタンのノート
フェルディナン・ド ソシュール 東京大学出版会 売り上げランキング: 320,111
Amazon.co.jpで詳細を見る
ソシュールは、言語学の祖とされている、19世紀初頭の学者で、現代の「構造主義」という思想の源流にも位置付けられる人。
僕は理工系の大学にいるんだけど、そのせいか、人文・社会の話に興味がある人があんまり周りにいない。いるのかもしれないけど、観測できない。個人的にはそういう話もとても面白いと思っているから、本当はもっとそういう話もできると楽しいだろうなあと思っている(とは言っても、僕自身大学に入ってしばらくはそうだった)。
中でも、何かを作る、ということの関連で言うなら(工学部は結局は何かを作る)「思想」というのは大事だと思っている。有形無形に関わらず、あるものに確たる意味付けを与えるためには思想が必要で、思想は社会を根本のところで支えていると感じる。構造主義だってそんな思想の一つだ。
僕は、「当たり前」がどうして「当たり前」なのかということが結構気になるタチだ。それが分かると、今の「当たり前」を超えられるんじゃないかと思うし、それが分からなければずっと同じ「当たり前」に閉じ込められたままになると思う。「当たり前」だと思っていたことを超えて新しい地平が���けるのは、一種の快楽��。
だから歴史が好きだ。歴史は今とは違う「当たり前」を教えてくれる。ある「当たり前」がどの時点でどういう出来事によって「当たり前」になったのか。そこにはどういう意図があったのか。あるいは、意図というのはなくて、構造的な変化があったのか。
前提が異なる世界を体験するっていう点で言えば、アニメやマンガ、小説といった物語もそうだ。必ずしも全ての物語に入り込めるわけではないけれど、没入できたときの一つの楽しみはその「当たり前」を超えられるところにあると感じる。
言語に話を戻すと、言語は、僕を含めあらゆる人にとって最も「当たり前」な社会的制度だと言える。ソシュールは、この「当たり前」に挑んだ。言語を科学的に扱い(特定の言語を超えて、言語を取り出す)、その上で、論理的な規則の抽出などに留まらない、言語についての哲学的見解を持つことを目指した。言語は全ての人にとって重要な制度なのだから、その学問に対する関心は一部の専門家に留まらないものであるはずだ、という信念を持っていた。
言語についての学問、言語学というのがあり得るはずだ、とソシュールは言う。
言語学は何を題材にすればよいだろうか。書き言葉だろうか、それとも話し言葉だろうか。語の配列についての論理的な規則を得れば十分だろうか。そもそも言語は「どこ」にあるのだろうか。
言語学の輪郭を描き出していくソシュールの議論は、驚くほど精緻で、明快だ。そこには、「当たり前だから」と最初から引かれたような線は無い。
この世界に生まれた子供が最初に目の前の「言葉」の秩序を受け入れざるおえないように、あることを学ぶのに際して、学問的な枠組みというのはあらかじめ与えられていて、その生成の現場を見ることはそう多くはない。
結果として、『一般言語学講義』はその創造の過程で言語についてのいくつもの「当たり前」を否定することになった。
中でも代表的なのは、言葉の恣意性だ。言葉は、音の並び(聴覚イメージ)と意味の結びつきでできている、と考えられるが、その結びつきは恣意的である、というものだ。
ここで、要素の集合が二つあって、そのあいだの写像に恣意性がある、という風には捉えない。重要なのは、意味について、集合における要素のような、明確に輪郭を与えられた何かをあからじめ仮定することはできない、という点だ。意味の輪郭は、対応する言葉があって初めて存在する。
そんなこと分かったって仕方ないじゃん、という向きもあるかもしれない。しかし、これは、言語を使っているだけで既に巨大な価値体系を了承しているということで、そのことはほとんど意識されない。「先に生まれた方を“アニ”」「後に生まれた方を“オトウト”」というように名前を付けることは、既にかなりの文化的な価値判断を含んでいる。英語で兄弟はどちらも“brother”だ。
書いていて気付いたことではあるけれども、ソシュールに連なるとされる学者だちも同様の志向性を持っている。レヴィ・ストロースだとなぜインセスト・タブー(近親相姦の禁忌)はあるのかだとか、フーコーだと「見る」ことの権力的作用だとか。まだ原典には当たっていないけれど、西洋から輸入された「教室」の、全ての生徒を教師から一望できるようになっているという「当たり前」に潜む権力性、とか興味をひかれる。
「当たり前」を越えていくのは楽しい。
0 notes
takenos · 9 years
Text
ゲームの動画サイトつくった話
こんにちは、たけのです。
今日は昨年くらいから運用している Web サービス、VS-SEED.NETについて紹介してみたいと思います。ざっくり言うと、これはとあるゲームの対戦動画が見れるサービスです。
機動戦士ガンダムSEED DESTINY 連合 VS. Z.A.F.T.II
何よりもまずはゲームの説明��しなければいけません。
『機動戦士ガンダムSEED DESTINY 連合 VS. Z.A.F.T.II』、通称『連ザ』というゲームがあります。このゲームは2対2で戦うアーケードゲームで、ゲームセンターに置かれています。いわゆるVS.シリーズの一つで、『機動戦士ガンダム 連邦vs.ジオン』から今まで続いています。最新作は、『機動戦士ガンダム EXTREME VS. MAXI BOOST』です(長すぎる)。
VS.シリーズに共通するのは、プレイヤーがガンダムを操作して戦うことと、2対2で戦うことです。一緒にやる二人は隣同士に座って、反対側に相手二人が座って対戦します。勝つためには二人の連携が非常に重要になり、そこが面白いところです。
実際に動画を見てみましょう。試合は大体3分です(大会なので実況付き、試合は00:40〜)。4画面のうち3画面録画しています。
【ニコニコ動画】R.Z.J.C.2014 Bブロック 第六試合 連ザ久々 VS アベンジャーズ
…とここについてはいくらでも長くなりますが、本旨じゃないのでこれくらいにしておきましょう。
VS-SEED.NET とは?
VS-SEED.NET はこの連ザの対戦動画を見ることができるサービスです。動画はプレイヤーや乗っている機体に紐付けられていて、例えば上手いプレイヤーの動画を見る、ということができます。内部的には勝率とかも算出していますが、表示する順番を決めるのに使っていたり。
なぜ作ったか?
根本的には、このゲームが好きでこのゲームをより楽しみたいというところから出発しています。VS-SEED.NET はそのための一つの試みです(楽しくないと対戦相手が減ってしまうという切実な事情もあります)。
ゲームをそこそこやっている人なら分かると思いますが、他人のプレイしている動画を見るのは非常に面白いです。神がかったプレイや、緊迫した試合を見る面白さは、スポーツ観戦とも共通しています。ウメハラの動画なんかは結構知っている人もいるんじゃないでしょうか。
【ニコニコ動画】ストリートファイター Ⅲ ウメハラ神の逆転劇&手放し戦法
ただ、連ザの動画をインターネットで公開するのにはいくつか障害があって(問題その1)、あまりインターネットに上がってくることはありません。また、上がってきた動画も上手に整理されているわけではありません(問題その2)。これをどうやって解決するかですが…
問題その0:どうやって撮るか?
実はこの前にもう一つ問題があって、そもそもアーケードゲームの対戦をどうやって録画するか?という問題なのですが、既に解決している人がいたのでありがたく使わせてもらいました。録画自体は僕がゲームセンターで行います。
連ザ2大会・対戦会告知etc...ブログ : 録画
問題その1:撮ったあとが面倒
動画の公開は普通にやると1試合ごとの切れ目を見つけて分割し、出来たファイルを一つずつ動画サイトにアップロード、という工程になるんですが、これが純粋にとても面倒。これはそういうソフトウェア・ユーティリティを作ることで解決しました。技術的には少し課題がありましたが、やるべきこと自体はとても単純。
このユーティリティはvs-seed-publisherにまとめています。
問題その2:動画が整理されていない
いくら動画をアップしても、それに対してのアクセスが容易でないと意味がありません。上手い人の動画だけ上げればいいかと言うとそうでもなくて、なぜなら皆それぞれ自分の動画を見たいからです。
ここでは、考えられるユースケースを3つのパターン+その複合(AND)に絞って、それに基いて Web アプリケーションをデザインしました。
あのプレイヤーの動画が見たい!
先週の日曜日の動画が見たい!
この機体の動画が見たい!
ちなみにこのパターンでカバーできていないマイナーなニーズとしては、「この機体のあの覚醒コンボがみたい!」といったケースが挙げられます。
あとは、自動でアップロードした動画が簡単にこのサイトに反映されるユーティリティを作って問題その1と接続して完成です。
…という感じでちょっと綺麗に説明しちゃいましたが、これは今のサービスを説明しているので簡略化されていて、製作する上で辿った道筋はもうちょっと異なります。例えば、最初はログインしてお気に入り登録する機能とか動画にコメント流す機能とかあったんだけど、消滅した等。
そのあたりはまた気が向いたら別に書こうと思います。
ではでは。
0 notes
takenos · 9 years
Text
在来線で長距離移動する
こんばんは、たけのです。 僕は実家が滋賀にあります。普段、東京から帰省するときは新幹線を使うんですが、この年末年始は節約のために青春18きっぷを買って在来線で移動しました。高校生以来です。 青春18きっぷというのは、2,370円でJRの在来線が一日乗り放題になるものが5日分セットになった切符ですね。 大津から横浜への移動はこんな感じ。 昼前に出て付く頃には暗くなってるって感じですかね。
Tumblr media
昔から僕は乗り物としては車よりも電車が好きなんですが、在来線での移動はいくつかポイントを踏まえれば意外に安くて快適な旅になるなあという気がしています。 高速バスと比べて個人的に在来線の良いと思うところ。 - 渋滞がない/遅延が少ない - 隣に座る人がいない/隣に座る人を選べる - 好きなときに出発できる - 高速道路より景色が楽しい - 区間ごとに時間を有効に使える - 気が向いたときに自由に降りられる(18きっぷの場合)
Tumblr media
人によっては以下がデメリットになるかもしれません。 - 夜間に寝ながらの移動ができない - 混んでない時間/日時を選ぶこと - 18きっぷ使わないとやや高い - 18きっぷは5回分を使う/売却する必要がある また、快適な旅をするためにはいくつかやっておくことがあります。 - 車内での時間の使い方を考えておく - 帰省、通勤、休日など、 電車が混んでる日/時間帯はできるだけ外す - 荷物は置き忘れないために、できるだけ軽く、一つにまとめる(必要のない荷物は送っておくのもあり) - 何番ホームに乗り換えるかのアナウンスが直前に流れるのでそれだけ聞いておく - 乗り換えのタイミングを気にしなくてもいいようにリマインダーを利用 ちなみに今回は新書1冊を読み、映画1本を見て、あとこの記事を書くことができました。
Tumblr media Tumblr media
以上、在来線も結構良いよっていうお話でした。
0 notes