けものみち

まったりと、きのむくままに。

M1後期の振り返り

こんにちは。もう早いもので修士課程もあと1年となります。

というわけで、M1後期の振り返りを書いていきます。

講義

履修した講義は、

  • 情報教育特論(月曜2限)
  • 生物圏情報学(火曜4限)
  • ヒューマンロボットインタラクション(水曜3限)
  • 分散情報システム(水曜3限)
  • 情報と知財(木曜5限)

です。単位は無事に全部取り切ったので、これで学部4年+修士1年目の計5年間一つも単位を落とさずに卒業できそうですね。

情報教育特論

教育系の研究のお話です。前半6週程度は普通に講義やって、後半はワークショップでした。 ワークショップは3つのテーマから1つ選んで3人1組でやる感じです。グループの決め方がかなり恣意的で訝しかったのと、やる内容は自由に決めていいけどそれなりに成果出してね、って感じで準備が雑なうえに、評定もそこまで高くないという感じであまりいい思い出はないです。


生物圏情報学

生物系の分析でよく使うモデルとか、時系列データ分析の話とか、研究の話とかしてました。 リモートで資料配られて数回ある課題を出すだけなので、普通の講義と同じかなと思います。


ヒューマンロボットインタラクション

人らしいロボット、ロボットと人とのインタラクションについての概論です。 毎回の講義における出席とディスカッションと最終レポートが評価基準です。 最終レポートは少々重ためですが、毎回の講義内容を軽く復習することと、全体の内容を踏まえての設問なので、こつこつやっていれば大丈夫です。講義の準備がとてもよくて、一番印象に残っています。


分散情報システム

DB系、データマイニング系のお話でした。講義形態は普通ですが、オンライン試験が2回ありました。


情報と知財

特許、著作権など、情報系と絡みのある法律や制度についていろいろ話していました。中身自体かなりためになると思います。


研究

Twitterを題材にした研究は新規性が出なさそうで諦めた結果、卒論の延長という形でクラウドソーシングを題材にした研究をすることにしました。

中間発表まででは、関連論文の調査と、実験データ収集開始まで行っているので、あとはデータが集まったらいろいろ手法をやってみてうまくいってくれないかな、という感じです。


バイトなど

高校生の模試の採点アルバイトはほとんどなかったです。収入激減。

TAは弊研究室の教授の担当講義の小テスト採点をしていました。簡単な採点ですが、人数が多いのでまあまあ大変ではありました。


インターン / 就活

内定を1ついただいて、そろそろ意思決定の時期に入っています。

アカツキ社のインターンに参加してきた

f:id:WhiteFox-Lugh:20210207205552p:plain

2/1~2/15 の平日10日間、株式会社アカツキ(以下、アカツキ)さんのインターンに参加させていただきました。このインターンにおいて、得た知見や経験、感じたことなどを本記事に記載しようと思います。

忖度などは一切なく、思ったことを素直に書いています。

今回行った業務の関係上、抽象的に書いてあり理解がしづらい部分があるかと思われますが、ご了承ください。

参加経緯

22卒新卒採用の選考過程で、インターン参加が決定しました。

自分はこれまでインターン経験がゼロであったため、働くイメージをもたないまま就職するとなると、万が一ミスマッチがあった場合、双方にとって不利益になるため、実際に働いてみて、業務内容や働き方、会社の雰囲気などをつかんでから意思決定をする方がお互いにとって良いだろうとのことでした。

アカツキさん自体は、大変失礼ながらサポーターズさんにご紹介いただくまで存じ上げておりませんでした。 そんな自分が、なぜアカツキさんに深く興味を持つようになったかというと、アカツキさんについて自分から進んで調べていき、ゲーム開発そのものや、制度面、企業の雰囲気に魅力を感じたこと、 面談や面接を通して、一緒にどういうエンジニアを目指すと良いか考えてくださったことが大きかったと思います。インターン参加が決定したときは純粋にうれしかったです。

面談

インターン実施1か月前ほどに、メンターさんとインターン内容について面談を行いました。ここでは、

  • インターンの日程
  • 機材の手配
  • 触りたい技術内容
  • 事前に勉強しておいたほうがよいこと

あたりの話をしました。

インターンの実装内容

タスク自体は3つで

  • ゲームのバージョンアップに伴って追加された要素を、既存の要素の仕様に合うように変更する
  • ユーザデータのキャッシュについて、不必要なアクセスを減らす
  • 内部ツールの改善

です。以下、それぞれについて簡単に記述します。

既存仕様に合わせる改善

インターンで最初にいただいたタスクです。

近年のゲームは、ゲームをリリースした後も新たに機能が追加されたり、アイテムなどの新要素が追加されることがよくあります。 この際に、先行でリリースされていた要素と、後発でリリースされた要素に関連性がある場合は、コード内で実装に一貫性をもたせておくことにより、メンテナンス性を高めることができます。

抽象的な書き方をしてしまったので、簡単に例を挙げておくと、ゲーム進行によりもらえる報酬やゲーム内通貨、アイテムなどの量を1単位としたときに、特定条件を満たしたときは多くもらえるように報酬の量を調整したり、アイテムを獲得する確率を通常より高くなるように調整したりします。この調整を、個々の要素ごとに倍率を一つ一つ値を定めて調整するのではなく、条件を満たした場合、すべての要素に一律の倍率補正をかけるようにすると、一貫性がとれてメンテナンスがしやすくなります。

今回、ある時期のアップデートで追加された要素が、その一律の倍率補正から外れた実装になっているので、 その部分を探し出し、修正を行ってほしいというのが最初のタスクの内容です。

はじめに、コードの調査を行いました。具体的には、GitHub のレポジトリ内を関連しそうなキーワードで検索したり、過去のコミットやプルリクからどういう変更があったかを読みました。 コードのどこかに原因があるからと、この課題の序盤ではほとんどソースコードを読んでいましたが、複雑な部分は社内 wiki に仕様書がおいてあるのでそれもあわせて読むと理解が早くなるとアドバイスいただきました。

この調査を進めていった結果、

  • Rails の settings.yml ファイルに定数が定義されており、特定条件を満たすと報酬がその定数倍になる
  • ゲーム内の抽選で、1つもらえるか、もらえないかが確率的に決定する要素が、特定条件を満たした場合、その定数に関わらず規定回数抽選、それ以外の場合は1回だけ抽選するようにコード内で固定されている

ということがわかりました。

この部分を settings.yml で定義された定数( n とする)を用いて、 n 回抽選するように書き換えます。 実装としては以下のコード(実際のコードと多少異なる)のような感じで、flag で特定条件を満たしているかどうかを判定し、 flagtrue なら n 回、false なら1回抽選という風にします。lottery は抽選を行い確率 ptrue (当たり)、確率 1-pfalse を返す関数です。

if (flag ? n : 1).times.any? { lottery(p) }
  (報酬がもらえる)
end

また、これが正しく動作しているかをテストするために、lottery の当選確率を0にして、lottery がぴったり n 回呼び出されるかというテストも rspec を用いて記載しました。

導入課題ということもあるので、タスクとしては取り組みやすかったのですが、エンジニアが積み重ねてきた数万コミットあるコードの中から、問題の原因となる部分を効率よく探す方法や、 実装に関連する部分を素早く的確に読むことが求められたと感じています。

キャッシュの不要なアクセスを減らす

2つ目のタスクです。

ユーザのアカウントやそれに紐づいた情報を取得したい場合、いちいちデータベースにアクセスするのは効率が悪く、ユーザの情報をキャッシュに保存しておくということをします。

キャッシュに置いてある情報は、ログイン日時の記録をする場合、ユーザが名前を変えた場合、ゲーム内で報酬を得てステータスが変更された場合、チートなどを発見して運営側がアカウントの凍結を行った場合など、さまざまな場面で更新する必要があります。しかし、データベースからレコードそのものを引っ張ってきてキャッシュに置くということをしている以上、キャッシュにおいてある情報自体もすべて利用するわけではありません。

既存のコードでは、キャッシュにおいてある、ユーザ関連の情報のうち、どれか1つの要素が書き換わったときにキャッシュにアクセスするという風にしていましたが、今回はキャッシュにおいてある情報のうち、実際に利用されるデータに変化があった場合のみキャッシュにアクセスし更新する、という実装を行いました。

実装としては、Rails の callback を利用し「特定のデータに変更があった場合、キャッシュを更新するフラグを立てて、キャッシュ更新処理を行う」という感じになりました。 擬似コードを書いておくと、

after_save do
  (キャッシュ関連のクラスのキャッシュ書き込みフラグを立てる) if (特定のカラムに変更があったかどうか)
end

after_commit { (キャッシュ書き込み関連の関数を呼ぶ) }

というイメージです。 キャッシュ書き込みフラグが立っているかどうかは、after_commit で呼び出される「キャッシュ書き込み関連の関数」内でチェックされます。

実装自体は簡潔ですが、キャッシュ周りの挙動を読むのがなかなか難しく、調査にかなり時間がかかりました。

次に、rspec を用いたテストを記述しました。

キャッシュの書き換えが行われる部分については、expect { subject }.to change { 対象の値 }.from(変更前の値).to(変更後の値) というコードで確認しました。 また、キャッシュに不必要な書き込みがないかのテストは expect { subject }.not_to change { 対象の値 }.from(元の値) というコードで確認しました。

自分は、最初 change を用いず、eq (変更後の値) と書いていました。コードレビューでは、何をテスト対象とし、どういう目的のテストなのかをしっかりコードで書き示すことを意識するようにご指導いただきました。

内部ツールの改善

3つ目のタスクです。

ゲームをつくる人はエンジニアだけではありません。プランナーさん、デザイナーさん、他社のエンジニアさんなど多くの人が関わってきます。 そういったときに、ゲーム内で利用されるデータを、開発者側で扱いやすい形で保存し、検索や取り出しができるようにすると、情報の共有がスムーズに行えるようになります。

今回は、ゲーム内のキャラクターに関する情報を、キャラクターID、名前など、さまざまな条件から検索できる内部ツールの改善を行いました。

実装した内容としては、

  • キャラ名の完全一致検索(部分一致は実装済み)
  • ID範囲検索
  • 指定したデータ、カラムだけ CSV 出力
  • キャラクターに関連する情報の表示

です。

キャラ名の完全一致検索は、Rails のデータベース検索における、where 句の基本的な使い方をそのまま利用すれば実装ができました。

ID範囲検索は、クエリでは 1-10 といったようにハイフンをつかって範囲を指定する形式で書くようにし、そのような形のクエリが来た場合は、 データベース検索で使えるように 1..10 といった形に変換処理を行った後でデータベース検索を行う、というように実装しました。

指定したデータだけ CSV 出力する機能については、今までの検索結果表示画面において、各キャラクターの情報の一番左側にチェックボックス☑を追加し、チェックが入ればそのデータを出力する、という風に実装を行いました。また、検索結果画面の最下部に、どのカラムを出力するか選択できるオプションを設置しました。

キャラクターに関連する情報の表示については、同じキャラクターでも、条件を満たすとより強いキャラクターに変化することがあるので、 現キャラクターの変化前、変化後の情報を表示してほしいという要望でした。

自分は、最初キャラクターのデータベーススキーマ定義からリレーションをたどり、変化前、変化後の情報などを定義したスキーマの情報をどう取り出すか考え、愚直に実装を行っていました。 メンターさんにコードや表示結果を見ていただいたところ、キャラクターの検索後、各キャラクターの詳細表示をするページがあるのですが、そこに現キャラクターの変化前、変化後の情報を表示する部分があり、そこの実装を参考にしてみるといいかも、というヒントをいただきました。このヒントをもとにコードを調査すると、現キャラクターのレコードを入れると、変化前、変化後の情報をとってきてくれるヘルパーメソッドが定義されていました。 その既存の実装を参考にすることによって、簡潔に実装を行うことができました。

時間の関係上、追加した機能におけるパフォーマンス面の改善までは手が届きませんでしたが、 ツールを利用する方々に Zoom ミーティングで UI、UX 面を確認していただきながら、要件を満たす機能を実装することはできたと思います。

学びなど

ゲーム開発について

ゲーム開発自体に興味はあったものの、実際に大規模なゲーム開発自体に携わったことはなく、いまいちイメージがつかめない状態でした。

今回のインターンでは、

  • どういう風にデータベースやコードの仕様が決定されているのかを仕様書やコードから把握すること
  • ユーザ数が多いサービスで、パフォーマンスをよくするためにどのような工夫がされているか

あたりは短期間ながら大まかにつかむことができたのではないかと思います。

今回のタスクでは、数日かけて調査して、書いたコードがたった数行というものがあります。それだけ、大規模なコードの中から不具合の原因や、改善点を調査するのに時間がかかるということです。また、個人開発と異なり、すべての仕様やコードを把握することはできないので、自分が担当する箇所のコードの挙動、やり取りされるデータの中身や型をしっかり把握することや、わからないことがあればほかの詳しい人に尋ねるというのも大事な行動の一つでありました。

スクラム開発

よく、「スクラムが流行りだ」とは最近耳にしていましたし、頭でもスクラム開発はどんなものかはふわふわとしたイメージながらもっていました。

実際にチームに所属してみると、円滑に開発を進めていくための様々な工夫として、

  • ツールを使ってタスクや進捗状況(未着手、着手、レビュー中、完了など)を可視化して管理している
  • 自身の進捗についてうまくいっている点や難航している点を正直に言語化し、チームで共有する
  • ペアプロやモブプロなどを適宜導入し、一人で悩む時間を減らすことや知見を共有し、開発効率を上げる
  • 業務のことだけでなく、朝会やランチ、夕会などで雑談をしてチームの交流を増やす

あたりは体験することができました。

コンプライアンス関連の話

開発そのものについて学ぶことも多かったのですが、インターン序盤で行われたオリエンテーションにおいて、開発を通じて知りえた情報の取り扱いについてのお話も個人的には大変勉強になりました。

エンジニアだとついつい自分が関連するプロダクトについて「俺はこんなことを作ってるぞ!」とか「このプロダクトのここが魅力的だ!」と語りたくなることもあるかと思いますが、そういった安易な書き込みが会社の発言ととられ、思わぬトラブルに発展してしまうおそれがあることや、リリース前の情報をネタバレしてしまい、企業の利益や信頼を損失する恐れがあるなど、コンプライアンス的な観点で学んだことも多かったです。

関わる人の多さ

たった10日間のインターンをとっても、Slack のチャンネルや 1on1 の Zoom ミーティングで手厚くサポートしてくださったメンターさんや、チーム内のエンジニアの方々、ほかの開発チームメンバーや、プロダクトマネージャー、自身の勤務を管理してくださった総務の方々、といったように関わった人はとても多かったです。

リモートワークという形態だったため、オフィスという物理的空間制約がなく、Slack のチャンネルを切り替えさえすればたくさんの人の会話や議論が見えたのも、人の多さを実感できた要因だと考えられます。そのためか、困ったときにメンションを飛ばすと、すぐに誰かが駆けつけてくれるという点はリモートワークの良い点だったのではないかと感じています。

最後に

インターン自体初めてで、刺激的な10日間を過ごせそうとワクワクしていた部分もありながら、自分の実装力不足や能力不足がひたすら露呈する10日間になるのではないか、と懸念もしていました。どちらかというと後者の方が気持ちとして強かったかもしれません。

参加して数日経った段階で開発そのものや、いろんな人とコミュニケーションをとっていくのが楽しいと感じていました。ものづくりをすることが好きなこと、人に喜んでもらうのが好きなこと、一日の大半をゲームに費やすことがあって依存症レベルでゲームが好きなことなど、様々な思いを巡らせ、自分自身ってこういうカラーを持っていたなと改めて考えることができたと思います。同時に、わからないことだらけで、自分の力不足も毎日痛感していました。メンターさんからは、できることは少しずつ増えていくものだから、焦らなくても大丈夫だよ、とアドバイスをいただきましたが、やっぱり力不足を感じると悔しいもので、空き時間で次の日は同じミスをしないように復習するというようなことをしていました。

また、ツイッター上で「お仕事いきたくない」など、自分自身のお仕事やライフスタイルに対して不満ばかりいう人を多く見かけていて、自分も将来こうなるのかな、と就活を通して懸念していた部分がありました。面談や面接だけだと、会社の雰囲気やライフスタイルってなかなかわからないもので、長期的に楽しくはたらくことができるか、そしてプライベートとお仕事を両立できるかについては、不安材料としてずっと残っていました。インターンを通してこの点は具体的なイメージをもつことができたので、大きな収穫だったのではないかと感じています。

最後に、インターン生として温かく迎えていただき、サポートしていただきました、すべての方々に感謝を申し上げたいです。本当にありがとうございました。

Monthly Report (Jan. 2021)

f:id:WhiteFox-Lugh:20210126080804p:plain

こんにちは。2021年が始まってもう1か月経とうとしています。 2021年にはあれしたい、これしたいと皆さんもいろいろ目標を立てたかと思われますが、順調に進んでいますでしょうか?

さて、今月から月間レポートを出すことにしました。毎月を虚無で終わらせないため、自分自身の振り返りをするためです。学業のこと、お仕事のこと、趣味のこと、その他ちょっとしたこと何でもいいので書いていこうと思います。

2021年1月

学業

1/22 に修士論文の中間試問が控えていました。 昨年の前半は、SNS(特にツイッター)を題材にして、タイムラインのインタフェースの提案をしようと考えていましたが、半年かけて新規性が出る見込みがなかったため、卒論の延長として、クラウドソーシングをテーマにした研究にシフトしました。

中間試問では、以下のことを報告しました。研究の具体的な内容についてはここでは触れないことにします。

  • クラウドソーシングにおける課題、問題点
  • 研究のモチベーション
  • 既存研究
  • 提案手法
  • 実験
  • future work

昨年のアドバイザー報告(指導教員以外に、2名の先生に研究についてアドバイスをいただく)において、専攻では応用を重視しているので、自分の研究が一体どういう風に使えるのか、応用されるのか、どういうモチベーションで研究をしているのかについてをしっかり説明できるようにすること、並びに、既存研究についてしっかり調査を行い、今すでに行われていることとそうでないことの区別をしっかりつけることについてはかなり言われていました。

実験については、年末年始に修論用の調査用サイトを作成しました。5日間ほどでテストまで含めてできたので、まとまった休みに感謝です。 内容としては、画像データセットにラベルを付けるタスクを依頼するのですが、とりたいデータが Amazon Mechanical Turk では取得できないため、外部サイトとして自分で設計する必要がありました。

中間試問自体は発表はそれなりにうまくいったと思いますし、指摘自体もだいたい想定していた通りだったので良かったと思っています。

就活

4社ほど並行で受けております。どうせあとで企業名出してまとめるつもりですが、先に書いておきます。

昨年のクリスマスイブにはアカツキさんの最終面接を受けて高評価を得られました。ただ、自分自身にインターン経験がないことから、2月にインターンで実務経験を積んでみて、合うかどうかを判断したほうが、双方良い判断ができるのではないかという結論になりました。内定がでたわけではないですが嬉しいですね。 月末に、インターン機材(PCやWi-Fiなど)を受け取って準備を進めることになります。楽しみ。

残りの3社については、面接の終盤に来ていました。

1社目はサイボウズさんです。正直2次面接で言いたい放題言ったため、癖のあるやつだと思われて落ちたと思っていましたが、ロジカルに的確に質問に答えられること、コミュニケーション力が評価されていることがフィードバックで分かったので、最終は結構気合い入れて受けました。 ただ、結果としてはあと一歩足りないと伝えられ最終面接で落ちることになりました。フィードバックとしては、うちの企業じゃないとダメというこだわりや意欲がもう少しほしかったといった感じでした。うーん、悲しい。

2社目は freee さんです。1次、2次と順調に来て、フィードバックでも論理的思考力が評価されており、順調に行けば良い結果になると自信を持って最終面接に臨みました。しかし、1次面接や2次面接とたいして変わらない内容について聞かれたにもかかわらず、いまいち役員の方とのお話が盛り上がらず、こちらも不合格に。エンジニアや人事の方に良い評価が得られても、役員視点からすると、あまりいい人には見えなかったのかなと、結構落ち込みました。

3社目は Yahoo! さんです。こちらは、書類→コーディングテスト→1次面接と来て2次面接でした。 事前に、技術領域で一番力を入れたこと、もしくは研究内容について5分程度のプレゼンを用意しておくことが求められていました。プレゼン内容としては、技育展で発表したアレでした。

drakscake.hatenadiary.com

もともと自分がスライドの構成やデザインをしていたので、ちょっと手を加えるだけで済みました。プレゼンの後には、普通の面接と同様の質問もありました。フィードバックでは「就活の軸がそれだとどのベンチャー企業にも当てはまる」とだけ返ってきたので、受けた直後は、最初によくないところが返ってきた時点でもう落ちたんだなと思って、その日はごはんすら喉を通らなくなりましたが、通過していました。

3回目の面接では、面接というより面談に近かったです。自分のなりたいエンジニア像やエンジニアになりたいと思ったきっかけ、企業選びの軸などを詳しく深掘りされました。あとは履歴書の内容確認、国レベルの賞罰があるか、働くうえでの留意事項(通院や持病など)の話もしました。オファーを出す準備はできているという話がありましたが、アカツキさんと迷っているので、今すぐオファーを出してしまうのではなく、じっくりエンジニアと面談を重ねて意思が固まったところでオファーを出しましょう、という感じになりました。この回も、フィードバックがあったのですが、簡単にまとめると

  • プレゼンやコミュニケーションが上手(わかりやすい、ロジカル、質疑応答の際に補足スライドを使っていて準備がよく、相手のことを考えてコミュニケーションが取れる)
  • 就活の軸に具体性が足りないところを改善されてとても良い
  • 競プロやプログラミングを通じたものづくりなど、完遂力が高い
  • 一方で、我流かなと思われる部分もある

といった感じでした。おおむね高評価だったと思います。

趣味

音ゲー関連で、楽曲のジャケットイラスト制作をしていました。 某企画で4枚描いているうちの4枚目が描き終わったので、依頼は完遂したことになります。発表されたら告知しようと思います。

タイピングについては、最近あまり練習をしていなかったことと、周りの人がどんどん記録を更新していく中、このままだとタイパー界隈から通報されそうな気がしてモチベーションがわいてきたので、寿司打や e-typing を久しぶりに詰めることにしました。

寿司打について、既存の自己ベストを少し上回る記録を出すことができました。

ただ、この記録についてはまだ伸びしろがあるのでこれで満足はしていないです。

e-typing の腕試しローマ字については、これまでの自己ベストが 703pts (ワードセット:元気が出る言葉)でしたが、今回詰めたところ、743pts (ワードセット:元気が出る言葉)を出すことができました。これについては、正直自分でも驚きです。

703pts を出したときは手元動画が撮れていなかったので、今回は絶対撮影しようというお気持ちでずっとスマホのカメラを回していました。よって、今回はちゃんと動画も撮影できています。

今回のこの記録については、タイパー辞典さんにも名前を掲載いただけました。

w.atwiki.jp

このランキングについては、多少チート疑惑がある記録も載っているとはいえ、タイパー界隈では有名な方とようやく肩を並べることができたのでうれしいです。何より、e-typing って20年ほど毎週ランキング開催されている中で、たった百人程度しか700越えを達成できていないのが驚きです。まだ伸びる余地があると思うので、頑張ってレジェンド級の人の背中が見える程度にはタイピングの腕を磨きたいですね。

おしごと関連

学部生の科目のTAをやっているので、ひたすら採点業務をしていました。 1回の小テストあたりだいたい300人くらいの答案が来るうえ、これを一人で全部見て点数付けているので、1問あたりのウェイトが小さくても、結構大変です。

あと1回分小テストの採点が残っているので、頑張りたいと思います。

その他

新年早々、京都三条にある「ダイニング正義」で肉を食らいました。

300gアンガスビーフ、ごはん味噌汁セット、わさびトッピングで1700円程度です。学生でもこの値段普通に出せるし、肉もおいしくておなか一杯になるし、お店の雰囲気もおしゃれですし、人気店かと思えば全然並んだこともないのでおすすめです。