task4233のめも

書きたいことをつらつらと

気が沈んだ時や不安な時にやっていること

この記事は目黒ワンニャンパーク Advent Calendar 2021 の 6日目の記事として執筆されました。7日目の記事はeuxn23さんのこれが本当の目黒ワンニャンパークだです。

はじめに

こんばんは。task4233と申します。Goが好きで、最近は誕生日にCTFを開催してた大学院1年生です。

本記事ではタイトルにもある通り、気が沈んだ時や不安な時に意識的にやっていることをポエムにしたものです。このポエムで書かれていることは100%正しい訳ではないので、参考程度に留めていただければ幸いです。

TL;DR

  • 課題の分離をすると良いかもしれない
  • わだかまりを何かに書き出すと良いかもしれない
  • 瞑想をすると良いかもしれない

もくじ

この記事を執筆するに至ったきっかけ

最近、将来について考える機会が増えたり、人と関わる機会が増えたりしたためか、気が沈んだり猛烈な不安に襲われたりすることが増えてきました。

今までは、こういう時には不安の根源が何なのか考えて、その根源を改善するために何ができるのかを考え、それでもどうしようのない場合は友人に相談することで解消してきました。実際に、本アドカレの発足者である、なかひこさんにもお話を聞いていただいたこともあります。その節はお世話になりました。

しかし、仮にその結果自分で納得したとしても*1、その全てが精算される訳ではなく、多少のわだかまりが残ります。部屋を頑張って掃除しても、隅の方にホコリが溜まっていくようなものです。

このわだかまりは通常時間と共に消えていくのですが、最近はこの回数が増えてきたので、どうしようかと悩んでいました。

そこで、色々と調べてみました。

その課題はあなたが介入できる課題なのか

まず最初に手に取ったのは、嫌われる勇気という本でした。この本は、悩みを持つ青年が哲人と会話をしながらアドラー心理学に踏み込んでいく本です。このアドラー心理学は賛否両論ありますが、人間関係に苦しんでいた高校生くらいの時に読んでみて救われたので、私は良い本だと思っています。

話が逸れましたが、この本では「課題の分離」という概念が提示されています。この「課題の分離」とは、その課題があなたの課題なのか他人の課題なのかを切り分けて考え、お互いに相手の課題に踏み込まない概念のことと私は理解しています。「課題の分離」をすることで、あなたが介入できる事柄と介入できない事柄に分けて考えることができ、困難な状況の解消に繋がることが多いです。

この分離には下記の2つの質問に照らし合わせて考えることができます。

  • その課題の責任を最終的に負うのは誰か
  • その課題の結論を最終的にだすのは誰か

要するに、その課題の主体は誰なのかという話と似ていますね。主体があなたならばそれはあなたの課題でしょうし、他人なら他人の課題のはずです。

例えば、「Twitterのタイムライン上に鬱陶しい人のツイートが表示されていたので、あなたが気分を害した」という場合を考えます。この場合、

  • あなたが介入できる事柄
    • タイムラインに表示されるツイートの設定
    • 鬱陶しい人のブロック・ミュート
  • あなたが介入できない事柄
    • 鬱陶しい人のツイートそのもの
    • 鬱陶しい人の性格・考え

のように分離できます。そのため、この場合は、あなたが介入できる事柄である、ツイート表示設定の変更をすることで問題を解消できます。逆に、鬱陶しい人に対して、取り消しをお願いしたり、思考を正すように言ったりするのは、相手の課題に踏み込む行為なのでしない方が良いと思います。

本の中では人間関係に絞って考えていますが、この考えを一般化して捉えると、その課題はあなたが介入できる課題なのか、それとも介入できない課題なのかになると思います。気が沈んだ時や不安な時にこれを実践すると、意外と簡単に課題が解消されることもあります。

そのため、課題がある時には課題の分離をして、

  • あなたが介入できることは改善タスクに積む
  • 他人の課題には介入せず関わらないようにする

とストレスフリーで良いと思います。

それでも、頭では理解できていても、モヤモヤすることもあるでしょう。そのモヤモヤはどのように解消できるのでしょうか。

モヤモヤ君へのおてがみを書く

そもそもモヤモヤとは、課題があるが課題が何なのかが分かっていない状況にあると考えられます。Five Orders of Ignoranceの2OIや3OIに該当しますね。

下記の画像は質問に関する5OIですが、分かりやすかったので貼っておきました。

f:id:task4233:20211214031551p:plain
5OI

qiita.com

したがって、不明瞭な課題を明瞭にするための手段が必要です。ここで使えるのが、モヤモヤを何かに書き出す行為、通称、モヤモヤ君へのおてがみです。

このおてがみは、簡単にいうと、あなたのモヤモヤに向き合うヒントを見つけるために、手紙で語りかけるように書き出す行為です。下記の記事がまとまっているので、興味のある方は1度目を通してみてください。

style.nikkei.com

この施策がうまく刺されば、1OIに持っていけるので、その後課題の分離に基づいて次のアクションをとれば良いです。

私はこのモヤモヤ君へのおてがみをGitHubのIssueで管理しています。こちらがIssue Templateになります。

https://raw.githubusercontent.com/task4233/life/8df894dafccf86108207517c07ad646019655d10/.github/ISSUE_TEMPLATE/self-therapy.md?token=AHCLCSBLG2MIP4PJHYIO6FLBYDA2C

そして、恥ずかしながら、このテンプレートを使って書き出したIssueの例がこちらです。

f:id:task4233:20211214032051p:plain
前に書いたやつ

黒歴史ですね、もしかしたらこのブログもモヤモヤ君に届くかもしれません。それはまた別の話です。

瞑想も1つの手段ではある

今までで書いてきたのは、ポケモンでいう「はねやすめ」のような大幅回復系の手段だと思いますが、毎ターン少しずつ回復してくれる「たべのこし」のようなものがあるとより良いですよね。

その手段として使えるのが寝る前の瞑想です。この瞑想は坐禅を組んでやるようなカッチリした瞑想ではなく、マインドフルネス瞑想と呼ばれるものです。

私はYouTubeの音声に従っているだけなのでよくわかりませんが、簡単にいうと心を落ち着かせて1日を振り返る行為のことです。その音声でとても良いなと思っているフレーズが、今日という1日が良かった人も、そうでなかった人も、あなたがその時にできた最善の選択をとってきたことを理解しましょう といったフレーズです。

結果的に良くない結果、行為になってしまったとしても、人はその時に良いと思って行動しているはずです。自分から悪いと思って行動する人はそもそもその行動をしないと思いますし。だからこそ、やってしまったその行為への罪悪感を反芻するのではなく、その時のベストだったんだからしゃあない、くらいの気持ちでいると気が楽です。

おわりに

読み返してみると、結構なポエムになってしまいましたが、誰かのためになれば幸いです(なるのか)?

7日目の記事はeuxn23さんのこれが本当の目黒ワンニャンパークだです。興味があればご覧になってみてはいかがでしょうか?

*1:こういう時は納得した気になっているだけで、根本の問題は解消されていない気がします

CODE BLUE 2021 @TOKYO 学生スタッフ 参加記録

こんばんは。task4233(@task4233)です。

2021年10月19日-20日の2日間、東京ポートシティ 竹芝ポートホールで開催されたCODE BLUE 2021 @TOKYOに学生スタッフとして参加してきました。

今回は2回目の参加であり、前回の参加記にも書いた通りスピーカーアテンドを希望してスピーカーアテンドに従事させていただきました。

兎にも角にも, CODE BLUEは非常に楽しめたカンファレンスでした。来年度も縁があって参加できるようならば, スピーカーアテンドに挑戦するつもりです。

ref: CODE BLUE 2019 @TOKYO 学生スタッフ 参加記録 - task4233のめも

学生スタッフの概要に関しては上記の2年前の記録に書かれているため、今回は下記の3点を共有するために本記事を投稿します。

  • スピーカーアテンドの概要
  • スピーカーアテンドとしてお手伝いした感想
  • 改善されると良いなと思ったこと

もくじ

スピーカーアテンドとは

スピーカーアテンドの責務は、スピーカーが気持ちよく講演できるように全力を尽くすことです。基本的な業務は下記の2点です。

  • いらっしゃったスピーカーを待合室にご案内すること
  • スピーカーを登壇前に発表場所までご案内すること

ただし、これ以外にも言語化されていない業務は複数あり、いかにスピーカーに気持ちよく講演してもらうかを意識して、臨機応変に自分の頭で考えて対応する必要があります。

スピーカーアテンドとしてお手伝いした感想

非常にやりがいのある仕事でとても楽しかったです*1

最低限しなければならないことは定義されていますが、他の作業はベストエフォートです。私は同じ作業を淡々とこなすよりも色々と考えて作業する方がワクワクしますし、体を動かす方が好きなので、今回の業務に明示的に含まれていなかった業務フローを勝手に追加したり、一部フローを変えたりして従事させていただきました。

その結果、担当させていただいたスピーカーに感謝を伝えられることが何度もあり、スピーカーの方々に気持ちよく講演していただくことができたと考えています。

改善されると良いなと思ったこと

COVID-19の影響です。アイツらのせいで色々と不自由があり、非常に残念でした。

そんな状況下でもオンサイトで開催していただいた運営メンバー、ご協力いただいたスポンサーの方々、登壇していただいたスピーカーの方々に深く感謝いたします。

学生スタッフがより楽しくなるムーブ

来年参加する学生に向けて、老婆心ながら2つだけ書いておきます。

  • 名刺の作成
    • 名前、所属、SNSアカウント、連絡先等は書いておくと良いと思います
    • 渡すときに簡易的な自己紹介ができると良いと思います
  • 気になった業務の相談
    • 業務をやる上で、「こうだったら良いのに...」と思ったことはスタッフに相談した方が良いです
    • 大体改善されるので、改善案も併せて提示すると良いと思います

おわりに

今回もおかげさまで非常に楽しめました。

前回の参加記に書いた通り、今回私はスピーカーアテンドとして参加させていただきました。そのため、次回はNOCメンバーとしてCODE BLUEに従事したいと考えています*2

そして、学生スタッフはセキュリティに興味のある他の学生との交流の場でもあるため、普段触れることのない技術のセキュリティに関心を持つきっかけにもなり得ます。今回だと、例えばゲームAIに用いられるGOAPシステム、ETC等に用いられるDSRCというプロトコルAndroid用APKファイルの構造などです。 少なくともCODE BLUEに来ている他の学生は、自分よりも強い分野を1つは持っていますし、他の学生と雑談するのも楽しみの1つなのかもしれません。

また、今回配信された動画は全てアーカイブとして学生に共有されるとのことで、後ほど閲覧できるのが非常に楽しみです。

セキュリティに興味がある学生は、他の場所では経験できないことを経験し知見を広めるチャンスです。そのため、来年度も募集がかかった場合は、ぜひ学生スタッフに応募してみてはいかがでしょうか?

*1:初日遅刻してしまったのは内緒です

*2:NOCメンバーの方々、なにとぞ......

ヤフーのインターンシップで広告配信システムの機能追加フローを一通り経験してきた

はじめに

こんにちは。 8/30(月)~9/10(金)で、Yahoo! JAPAN(以下ヤフー)のインターンシップに参加してきました。

about.yahoo.co.jp

そこで、ディスプレイ広告に用いられるコンテンツキーワードターゲティングに用いられるロジックの機能追加フローを一通り経験してきました。

コンテンツキーワードターゲティングとは

一言で言うと、広告をより適したページに提供する仕組みです。

コンテンツキーワードターゲティングは、広告が表示される掲載面を指定するターゲティングの一つです。広告を配信したい(または配信除外したい)ウェブページやアプリのコンテンツをキーワードで指定して、掲載面を調整します。

ads-promo.yahoo.co.jp

この技術はGoogle Adsでも利用されており、Keyword contextual targetingと題して運用されています。

support.google.com

経験したこと

今回は、中身のとあるコンポーネントに利用されるロジックについて、一通りのフローを経験してきました。

一連のフローとは、

  • 設計
  • 実装
  • リリース
  • A/Bテスト
  • 結果に対する考察
  • 改善案の提示

のことです。

設計と実装はどこのインターンシップでも経験できると思いますが、リリースとA/Bテスト、結果考察まで経験できたのが特に貴重でした。

また、A/Bテスト中やレビュー待機中に他のコンポーネントの実装や修正も経験でき、圧倒的進捗をうみだすことができました。

学べたこと

ブレのない開発のために、

  • 実装の目的を意識すること
  • テストのスコープを意識すること

が重要であることを経験を通して学びました。

今回は2週間のインターンシップでしたが、A/Bテストの実施とその考察までできたのは、手戻りがほぼなかったからだと考えています。

実際に、設計のための議論や実装のレビュー時に、「これの目的って〜だから、その設計は目的とズレてない?」や「そのテストって何のためにやるの?」といった指摘をいただけたことが何度もありました。

これらは言語化されていませんでしたが、私の所属した部署の方々は既に理解されていたようで、流石レベルが高いと思いました。

インターンシップを通して

基本的に手が止まっていた時間がなく、余った時間で常に何かをしていたので、2週間という期間ながら本当に満足度の高いインターンシップでした。

そして、学べたこと、経験できたことも幅広かったです。

  • 業務に利用した技術
  • 新たに経験できたこと
    • 実装のリリース
    • A/Bテスト

また、定期的に1on1やランチ会を実施してくださったおかげで、最初の1週間でかなりメンバーと仲良くなれました。その時に使った資料も、反響が大きかったので良かったなと思っています。

speakerdeck.com

おわりに

全体としての感想は、一言で言うと「レベルの高い環境だった」です。広告配信系が生み出す利益が多いのからかもしれませんが、KPIを強く意識していたと思いました。そのために、どのような施策をすれば良いのか、エンジニアが考えて実行していたので、レベルの高い環境だと感じました。

ヤフーは配属ガチャがあるので、今回の環境が別でも満たせるかは分かりませんが、少なくとも今回の環境は非常に良い環境だったと考えています。

最後になりますが、今回のインターンシップについて尽力してくださったメンターの方々、関わってくださった方々、ありがとうございました!

VOYAGE GROUPのTreasureに参加して圧倒的成長をしてきた

はじめに

こんにちは。task4233です。

8/9(月)〜8/27(金)の3週間、株式会社VOYAGE GROUP(以下VGと略します)のTreasureに参加してきました。

このエントリでは、前半に行われた講義の概要と後半のチーム開発についてサックリ書きます。
最後にも書きますが、Treasureは他のインターンシップでは得られない経験が多く、本当に素晴らしいインターンシップでした!

もくじ

Treasureとは

Treasureとは、VGのエンジニア向け3週間インターンシップのプログラムです。
今年度は、前半に現場のエンジニアから講義を受け、後半にチーム開発を行いました。

このインターンシップのコンセプトは、「学生のスキル成長」です。
そのため、インターン開始前から人事や講師、サポーター陣からサポートを受けることができました。
また、インターン中も1on1が実施されるなど、非常に手厚いサポートがありました。

詳しくは下記の記事をご覧ください。

focus.voyagegroup.com

このように、「学生のスキル成長」がコンセプトであるインターンシップがTreasureです。

5つの講義

この章では、それぞれの講義の概要と感じたことをそれぞれ書きます。

2021年度のTreasureでは5つの講義が実施されました。
その講義は、バックエンド講義、フロントエンド講義、インフラ講義、DB講義、アイデア講義の5つでした。

バックエンド講義では、peiさんによるGoのハンズオンが実施されました。
個人的には、Goの書き方よりもAPI設計の心得が学びになりました。

また、peiさんからは、昼休みの雑談でデータモデリングに関する話が聞けたのがとても良かったです。
ビジネスのデータの扱い方とデータ解析者のデータの扱い方が異なるという話からディメンション・モデリングの素養まで教えていただき、知見しかなかったです。ありがとうございました。

フロントエンド講義では、ちゅうこさんによるTypeScript+Reactのハンズオンが実施されました。
私はTreasureに参加するまでPureJSとVue.jsを少し書いた程度のひよっこだったので、バックエンド講義よりも学びが多かったです。
特に、バックエンドの都合をフロントエンドのロジックに紛れさせないために、境界面できっちりエラーハンドリングをする話が一番の学びでした。

インフラ講義では、SyotaさんTonoさんによる、AWS CodePipelineを用いたCI/CDの構築のハンズオンが実施されました。
私は普段GCPをよく使うので、GCPの各サービスにAWSのどのサービスが該当するのかを使いながら学ぶことができました。

DB講義では、t_wadaさんによる、データモデリングの概観説明とハンズオンが実施されました。
この講義では、2021年におけるRDBMSの位置付けに関する話が前半にあり、この内容が元々なかった視点だったので、特に学びになりました。

イデア講義では、きっしーさんとガイアさんによる、価値あるプロダクト(MVP)の見つけ方の説明とグループワークが実施されました。
この講義では、UNS(User/Needs/Solution)に分けて段階的にアイデアを考える手法をグループワークを通して体験することができました。

実際に、ここで出たアイデアが後半のチーム開発で開発されたので、良い議論ができたと思っています。

以上の5つの講義は、その全てにハンズオンが取り入れられており、手を動かしながら学べたのが実に良かったです。

実は、この講義内容や数はVGのクルー同士で議論して毎年改変が加えられるそうです。力の入れ方が凄いですね。

チーム開発

この章では、チーム開発の概要と感じたことを書きます。

チーム開発は、アイデア選定含め、後半の約1週間で行われました。
この開発期間では時間外開発(18時半以降の開発)が禁止されていたため、開発できる期間が限られていました。
そのため、各チームはアイデアの核になる要素を思索し、それを満たす最小構成の実装を行う必要があり、技術力以外のスキルが研鑽された1週間でした。

私達のチーム「ホリネズミ」は、最初の3日をUNS固め、1日を環境整備、最後の3日を開発に使いました。
前半UNS固めの段階で1度UserとNeedsを定義したにも関わらず、チームメンバ間で認識の齟齬があったために、その定義を放棄して1から考え直すこともありました。

正直、認識の違いはスルーすることも出来たはずですが、チームメンバがお互いに意見をぶつけ合うことでより良いアイデアを発想できたと思っています。
この絞り出されたアイデアを実現するためのコアな機能のみを実装することで、1週間という短い期間ながらも最後まで全力で走り続けた結果、なんとか動くものが開発できたのは良かったです。

この特徴的なエピソードとして、Socket.IOを用いたリアルタイムチャットの実装が時間的に間に合わなそうだということが最終日に分かったため、REST APIの実装に差し替えてポーリングする方針に変えたというエピソードがあります。最終的に動かないゴミになることはなかったので、このインターンシップにおいては良い選択だったと思っています。

そして、結果的に「ホリネズミ」はグランプリを受賞できなかったものの、CI/CD賞をいただくことができました。
賞の発表を聞いた時は、全力を出し切った後だったのでぼんやりしていて、あまりリアクションが取れなかったのをよく覚えています。

とはいえ、時間外の開発を許してくれればもう少し開発できたので残念という気持ちもあります。
しかし、後述するAjitingでチーム開発のことを忘れて技術トークをできたので、悪い面ばかりではなかったと思っています。

Ajitingでのお話

VGでは、業務時間後に有志が集まる習慣があります。これは参加自由でインターン中は毎日開かれていました。
Ajitingは好きなことを話す場なので、ISUCONのチーム練習を配信したり、競プロの問題を画面共有して解いたりする人もいました。
中には、原神や筋トレ、ボルダリングを布教する人もいました。面白い人がたくさんいるなと強く思いました。

Ajitingで深夜にJavaScriptの謎挙動でワイワイするTreasure生の図
Ajitingにて深夜にJavaScriptの謎挙動で遊ぶTreasure生の図

コロナ禍で人と定期的に話す機会が減っていた私にとって本当に楽しい時間でしたし、毎日別の話題で学びがあるのはとても刺激的でした。

おわりに

ここまでで、Treasureの講義の概要とチーム開発、Ajitingについて書きました。

全体としての感想は、一言で言うと「本当に楽しかった」です。夏に圧倒的成長をしたいという全ての学生にオススメしたいインターンシップでした。

技術的な学びは言わずもがな、議論を進めるときの効率的な進め方やアイデアの発想方法、開発するときのコミュニケーションの取り方を体系的に学べたのが本当に大きな収穫でした。
その点で、当初の目的であった「スキル成長」は満たせていましたし、Ajitingとチーム開発によって横の繋がりができたので本当に有意義な時間になりました。

また、VGという会社が*1どういう会社なのかを知ることができたのも良かったです。
クルーの全員が考えて行動し、言われた仕事をやるだけ人間が1人もいないと感じられるほど、面白い方々ばかりでした。

最後になりますが、チームホリネズミのメンバー、Treasureに関わってくださったVGの皆さん、そして私と関わってくださった皆さん、本当にありがとうございました!

*1:今はCARTA HOLDINGSですが

アカツキの夏インターンシップで生まれた2つの成果とそこから得られた知見

はじめに

こんにちは。task4233です。

7/19~8/6 の3週間、株式会社アカツキの基盤開発等を行っているATLASチームにて、インターンシップに参加させていただきました。

aktsk.jp

そこで、私は下記の2つの成果を生むことが出来ました。

  1. APIの設計と実装
  2. パフォーマンスの検証と改善

この記事では、関わったサービスの紹介をした上で、私が取り組んだ内容とそこから得た知見を紹介し、最後にインターンシップ全体を通して良かったと感じたことを書きます。

もくじ

ゲーム内通貨管理サービス

このサービスの構成は下記の通りでした。

本体のゲーム内通貨管理サーバはGoで実装されており、本番環境ではApp Engine上で稼働しています。このサーバが各ゲームサーバに対してAPIを提供することで、ゲーム内通貨の管理をゲーム内通貨管理サーバに集約することが可能です。更に、管理されているゲーム内通貨はFlaskで実装された管理画面からも操作することも可能です。この操作権限を管理するために、権限を3段階に分けてAPI KEYとして利用者に提供しています。

また、ゲーム内通貨管理サーバは、権限を管理するための鍵を保持するSecret Manager、データを管理するDatastore、データ解析用のBigQueryを利用しています。

1.APIの設計と実装

まず、私はSecret Managerで管理している鍵のキーローテーション用APIの設計と実装に取り組みました。

キーローテーションとは、新たなバージョンの鍵を発行して古い鍵を失効させる仕組みです。これにより、セキュリティ強化が見込めます。

キーローテーションは手動で行うことも可能です。しかし、ゲームサーバが利用中の鍵を、誤って失効させるようなヒューマンエラーを防止するため、このAPIを設計および実装することになりました。

このAPIの設計と実装は、

  1. Swaggerの定義を書く
  2. 各エンドポイントの仕様について議論する
  3. 実装する
  4. レビューを通して実装を修正する

という順序で進め、設計と実装はサクッと終わりました。

サクッと実装できたのは、既存の実装が層ごとに責務が分割されていたためだと考えています。

既存の実装はコントローラ層、インフラ層、ドメイン層に分けられており、コントローラ層は受け取ったリクエストのハンドリング、ドメイン層はロジック、インフラ層では永続化と再構成といった責務の分割が為されていました。そのため、私は既存のコードを参考にしつつ、ロジックのユニットテストと全体のインテグレーションテストを書いて実装することが出来ました。

そのテスト中にPCが重くなることが何度かありました。原因を調査したところ、Datastoreのエミュレータがテスト後にゾンビ化していたことが判明しました。これに気づいた時に、Connectionが閉じられていないのでは?と思い、実際のコードを見るとClose処理が全くありませんでした。

ConnectionをCloseしないとディスクリプタを消費し続けるので、結果的にリソースの圧迫に繋がります。DatastoreのGodocには、下記の通り「終わったら閉じろ」と書かれていました。

Call Close to clean up resources when done with the client

pkg.go.dev

しかし、GoのGCがよしなにコネクションを解放している可能性も否定できませんでした。

そこで、実際に負荷試験を用いてCloseがパフォーマンスに及ぼす影響を定量的に判断することにしました。

2. パフォーマンスの検証と改善

チーム内に既に負荷試験を実施していた方がいたため、その方と話しあいながら負荷試験を設計しました。その方曰く、負荷試験で大事なのは、遅くなりそうな場所を予測して、その特定の場所に的を絞って計測することとのことでした。そのため、調査したかったDatastoreのClientが持つConnectionの生成を行うハンドラについて、Close有/無の場合で2回負荷試験を行いました。

その時の負荷試験は下記の通りPR上で計画しました。

今回の負荷試験はLocustを用いました。選定理由は、チーム内で既に行われていたのがLocustを用いた負荷試験だったためです。この検証を始めたのがインターンシップ終了5日前だったので、つまらない部分で躓かないように選定しました。

検証環境はLocustを動かすためにGKEを用い、検証対象サーバはGoを動かすためにApp Engineを利用しました。 そして、LocustのWorkersから1000RPS*1〜5000RPS程度飛ばしました。 この値に設定したのは、今回のテストがConnectionの生成のみをテスト対象としたためです。 全体の負荷試験を行う場合は、そのサービスのSLOを満たすレベルの負荷試験を行うと良いそうです。

さて、話を戻すと、行った負荷試験の結果がこちらです。

Closeあり

Closeなし

この結果から、下記の事実確認と考察が出来ました。

  • Closeを行うことで500エラーは100%減(22->0)
    • 500エラーの原因はGCPのログからメモリ枯渇と判明
  • 平均応答時間は40%増(95[ms]->133[ms])
    • 新たにClose処理を加えたためと考えられる
  • 4000RPS付近からCloseの有無に関わらずレイテンシが増加

4000RPS付近からレイテンシが高くなっていた原因の調査

この原因となっているボトルネックを調査するために、ハンドラにトレースを入れて再度負荷試験を実施しました。

その結果、レイテンシが高い時のトレースと低い時のトレースで、インスタンスであるcontainerのCreateにかかる時間に大きな差があることが分かりました。

そこで、このCreateの実装を確認すると下記の2つの操作が行われていました。

  • 新たなClientの作成
  • middlewareの挿入

middlewareの挿入は、内部的にスライスに対するappend処理のみを行なっていたため重くない処理と判断し、更に新たなClientの作成の実装を確認しました。

そこでは、

  • Google CloudのライブラリでgRPCクライアントを生成する処理
  • mercari.ioのライブラリでそのクライアントをラップする処理

が行われていました。後者は型変換が行われていただけなので、前者が重くなる処理と結論づけました。

ClientPoolの実装によるパフォーマンスの改善

この重くなる処理と考えられる処理を軽くするために、このgRPCクライアントをプールすることにしました。gRPCの通信はステートレスな通信なのでプール出来ないと思っていたのですが、データの送受信がない時も関係のないデータを流し続けることで再利用ができるようです。賢いですね。

github.com

余談ですが、gRPCのコネクションプールは下記のコードがシンプルで良さそうでした。

github.com

使えることがわかったため、実装をして再度ClientPoolを利用する場合としない場合で再検証を行いました。

その結果は下記の通りです。

f:id:task4233:20210810113538p:plain

f:id:task4233:20210810112602p:plain

この結果から、クライアントをプールすることで平均応答時間は26%減(133[ms]->105[ms])になっていることが分かります。したがって、クライアントをプールすることでパフォーマンス改善に繋がりました。

以上が、インターン中に行なったパフォーマンスの検証と改善です。

学べたこと

学べたことは大きく分けて2つです。

1つ目は、機能を適切な層に分割して実装することで、可読性とテスト設計のしやすさが高くなるということです。

これは、新しく大規模なソースコードに触れたからこそ、設計を意識した実装の重要さを再認識することが出来ました。

2つ目は、ボトルネックを調査して改善するまでのフローを経験できたことです。

私は本インターンで経験するまで負荷試験を行ったことがありませんでした。そのため、ボトルネックを予測と計測を組み合わせて発見し、それを改善する経験ができたのは大きな学びにつながりました。

メンターさんの:+1:ムーブ

これは余談ですが、今回のインターンシップで、なかひこさんにメンターとして様々な面で助力いただきました。なかひこさんが実施してくださったものの中で、ありがたかったことを列挙しておきます。

  • 1on1ミーティングを毎日実施してくださったこと
    • 毎日相談できる時間が保証されるのは心理的に良かったです
  • 細部まで丁寧にPRのレビューをしてくださったこと
    • 「なぜそうしたのか」という部分まで突き詰めてくださったのが良かったです
  • 1エンジニアとして扱ってくださったこと
    • 「これをやってみたい」と提案したことに対して全てYESで返すのではなく、必要性を議論しながら進められたのが良かったです

このような経験ができたのは、ひとえにメンターのなかひこさんとATLASチームの皆さんのおかげです。本当にありがとうございました。

おわりに

今回のインターンシップを通して、開発中のプロダクトに触れることで気づけた設計の重要性と、負荷試験の流れを経験しながら学ぶことが出来ました。

このインターンシップで得られた知見は、今後の開発で十分生かせると思います。

今回、良いインターンシップになるように尽力してくださったアカツキの皆さんには本当に感謝しています。 ありがとうございました!

*1:Request per Seconds

SecHack365 2020 研究駆動コース参加記録

はじめに

こんにちは。task4233です。

この度は、SecHack365 研究駆動コースのトレーニーとして1年間研究をさせていただきました。そのまとめとして、本エントリを書くことにしました。

なぜSecHack365に申し込んだのか

一言で言うと、大学にセキュリティ系の研究室が無かったためです。私がセキュリティ系の研究に興味を持ったのは昨年度のセキュリティ・キャンプ全国大会でした。そこで、マルウェアの検知手法に意外と単純なシグネチャ比較が用いられていることを知り、「これなら私でも手を出せるのでは?」と思い始めたのがきっかけでした。しかし、残念ながら私の所属している大学にはセキュリティ系の研究室がありませんでした。そのため、研究室がないなら外部で研究できるところを探そう!と思い、SecHack365の研究駆動コースに応募しました。その結果、合格しました。

SecHack365で何をしたのか

SecHack365では、マルウェア検知システムの提案と一部実装を行い、ポスター発表を行いました。

github.com

ポスター: https://sechack365.nict.go.jp/achievement/2020/pdf/2020_32.pdf

全体のスケジューリングについては、他のトレーニーの参加記録に書かれていると思うので割愛します。

blog.sechack365.com

一方で、他のトレーニーが書いていないであろう「オンライン開催」の感想を書こうと思います。
正直なところ、研究駆動コースにおいては「オンライン開催」は正解だったと考えています。なぜなら、定期的にオンラインでゼミを実施することが出来たためです。これは他のコースでも行われていたかもしれませんが、現状で何が出来ていて、何が出来ていないのか、そして次は何をすれば良いのかが明確になるため、日々の開発、研究の振り返りをすることはとても大切だと考えています。

逆に、「オンライン開催」で残念だったのは、旅行に行けなかった日本各地で対面でのお話が出来なかったことです。実は対m......おっと誰か来たようです。

挑戦と挫折の繰り返し

私はマルウェア検知システムに、CFG(Control Flow Graph)というプログラムの遷移状態を持つデータ構造を利用したのですが、その生成と利用に関して色々な角度から挑戦しては何度も挫折を繰り返しました。

ja.wikipedia.org

ざっくり話すと、最初はCFGの生成にLLDBというデバッガのC++APIを用いていたのですが、3カ月ほどかけて実装が難しいことに気づきました。そのため、比較的遅めなGDBPython APIを用いてなんとか実装し、最終的にCFGの生成部を実装することが出来ました。LLDBからGDBを用いた手法に変えるのに、3カ月も要してしまった理由はLLDBは高速なC++ APIを用いていたのに対して、GDBは遅めのPython APIを用いていたためです。今思うと、動くモノが出来ていないにも関わらず、最初から速さを意識して実装に取り組んでいたのは勿体なかったと思います。そのため、ここに時間をかけずに、もっと短いスパンで様々な手法を試すことが重要だったのかなと今思っています。

SecHack365では何が得られるのか

SecHack365全体では、イノベーティブな友人関係が得られます。多くの方は、SecHack365に対して「1年間で圧倒的成長」や「セキュリティつよつよになって帰ってくる」といったイメージを持っているのかもしれません。それは事実なのですが、それ以上にイノベーティブな友人関係が出来るのは大きいと私は考えています。なぜなら、SecHack365は事実上期限がありますが、友人関係は消えることがないためです。実際に、SecHack365を修了した今でも交友関係は続いていますし、今後も消えることは無いと思います。SecHack365を通して、この関係が作れたのは本当にありがたかったです。

また、習慣化が根付いてくるのも特徴の一つだと思います。SecHack365のトレーナーには習慣化のプロがおり、そのトレーナーから習慣化のコツや取り組み方を教えてもらうことが出来ます。しかし、ただ話を聞いているだけでは習慣化を続けていくことは難しいと思います。この習慣化を定着させるためには、そのトレーナーの助言を聴くだけでなく、実践することが肝要だと感じました。

実際に、私はSecHack365に参加して、本当に忙しい時以外は日報を書くようにすることで、その日の振り返りを習慣化できました。日報が書けないくらい忙しいときでも、最近は風呂の中で振り返りを行っています。その結果、寝る前にあまり進捗が出ていない日でも、「今日はここまでできたからえらい」とか「今日は出来なかったけど、明日はこれをやってみよう」とかいうことを考えることが習慣化できるようになってきました。その甲斐あってか、最終的に習慣化大賞をいただきました🎉

大賞の景品としていただいた一口羊羹焼肉

研究駆動コースでは何が得られるのか

研究駆動コースでは、研究的思考を実践しながら学ぶことのサポートが得られます。これは以下のSecHack365における、研究駆動コースの概要文にも書かれていることです。

SecHack365「研究駆動コース」においては、いわゆる成果主義ではなくアイデア発想とその着想理由を大切にしていることから、いわゆる研究の基本的スタイルに合わせることをそれほど重要視しません。その代わりに研究プロセスをしっかり明確にさせるための特訓を行います。これにより、アイデアの着想に至った過程の重要さに気づいてもらい、研究へのモチベーションを高める支援を行います。 具体的には、アイデアの創出から始まり、その研究が誰に対してどのような効果や利点があるのか、何故それを実施してみたいのか、どうしてもやってみたいのか等々はっきりさせることが大切であり、トレーニーに求めることは今まで経験してきたようなドリルの問題を単に解くような「問題解決」スタイルではなく、自ら「課題設定」ができる能力を伸ばしてみたいという意欲を自身で持つ、ということが重要です。もう1点、単なる思いつきでは世界には勝てないということに気づいてもらいたいということです。よって、諦めない強い心を作り上げること、これがトレーナーたちが本コースを運営する上で最も重要視している点です。人によっては少し厳しい感じを受けたかもしれませんが、私たちは皆様のチャレンジを全力で受け入れられるよう身体を暖めながらお待ちしております。

sechack365.nict.go.jp

研究的思考、とは様々な側面がありますが、これは文面ではなく実践を通して学ぶものだと思います。そのため、興味が湧いた方は、ぜひ来年度以降の研究駆動コースに応募してみてください!

sechack365.nict.go.jp

おわりに

最後になりますが、トレーナーの皆さん、スタッフの皆さん、アシスタントの皆さん、そしてトレーニーの皆さんに支えていただいたことに対して深く感謝申し上げます。皆さんの存在は、私1人で出てくるアイデアを大きく膨らませる手助けになってくれました。私1人では、SecHack365での研究を形にしてポスターとして発表するのは難しかったと思います。その点で、アイデアや情報提供をしてくださった皆さんには本当に感謝しています。ありがとうございました。

最後に、いただいた修了証受理ツイートをもって締めさせていただきます。最後までお読みいただき、ありがとうございました!

2020年の振り返りと2021年の目標を述べてみる

はじめに

こんにちは。task4233と申します。

この記事は, 僕の2020年の振り返りと2021年の目標を述べることを目的として書かれたポエムです。
昨年のポストに引き続き, 書いてみました。昨年は思っていた以上に某ウイルスにダメージを受けて色々と大変な年でした。
これは皆さんが感じていることだと思うので, 上手く付き合っていくしかないのかなと思います。
昨年で得られた知見をいくつかに分けて書いたので, 少しでもお役に立てれば幸いです。

もくじ

2020年の振り返り

今年の目標は以下の5つでした。

  • [x] SecHack365に応募する
    • 2020年 SecHack365 研究駆動コース
  • [ ] セキュリティ・キャンプ全国大会2020のチューターに応募する
    • SecHack365, 教育実習に専念したかったので応募を断念
  • [ ] 高度情報技術者試験かセキュリティ資格試験AC
    • 某ウイルスで断念
    • 今年は受験予定
  • [ ] CTFの本番で正答率10~20%の問題を通す
    • WaniCTF SQL Challenge 2(26.7%)
  • [ ] セキュリティに関するOSSツール(拡張)を作る
    • SecHackで作成中
    • 今年公開予定

以上のうち, チェック([x])がついているものを達成しました。

全然達成していませんね。もちろん努力はしていたのですが, 予想通りには行かないものです。
引き続き精進します。

院進学と将来

色々な方々に相談にのっていただき, 結局そのまま同じ研究室で続投することに決めました。
この場をお借りして感謝申し上げます。本当にありがとうございました!

理由はいくつかあるのですが, 決め手となった2つの要素は, 来年弊学にネットワーク系の教授が配属されることと, 僕の研究分野において他大に行くメリットがそこまでなかったことです。

僕の研究分野は簡単にいうとお金にならない(?)ので全国の大学の研究室を探しても完全に合致する研究室はありませんでした。微妙に被っている研究室が筑波大にあり, 受け入れていただく流れになっていたのですが, 色々な方々に相談させていただき総合的に判断した結果, そのまま他大に行かずに院進することに決めました。詳しく書くと色々と問題がありそうなので, 他大の院に行くかどうか迷っている方がいれば, 内々で相談にのれるかもしれません。DMを飛ばしてください。

また, 将来的にはやはりエンジニアの方面に進みそうな気がしています。
研究者も悪くはないのですが, 現状で研究の楽しさよりも求められた要件をクールに解決するコードを書く楽しさの方が勝っているので, そちらの方面に進みそうです。
そのために, 会社(業界)を知り, 優れた仲間を見つけ, スキルアップするために, 今年は積極的にインターンに応募するつもりです。おススメのインターン等ありましたらお教えください。

エンジニア種別としては, バックエンドエンジニアになりそうですが, バックエンドだけに限らずフルスタックを目指して精進していきたいと思います。

誕生日CTFの反省

今年も12月5日に誕生日CTFを開催しましたが, 結論から言うと, 下記の謎問題たちを出題してしまい, あまり芳しくないCTFとなってしまいました。

  • パラメータを変えずに連続アクセスすると得られるWeb問
  • アクセス権限不備で想定解以外でも得られるWeb問
  • 論理性が欠如したOSINT問

これらの対策は下記の通りです

  • 環境構築も含めた問題管理
  • 事前の難易度確認と調整

さて, 謎問題たちは僕の手で生み出してしまった訳ですが, これらのうち上2つはサーバの設定不備により問題環境が蒸発したために生まれてしまいました。もちろん問題はGitで管理していたのですが, 本番環境のアクセスコントロールはnginxで行っていたため, GKEのインスタンスがおしゃかになってしまったときに対応できなくなってしまいました。 対策として, KosenXmasCTFのように, 各問題それぞれをDockerfileで切り離す手法が取れそうです。そうすることで, docker-composeかk8sで一括管理できるので, 来年はそうするつもりです。

OSINT問に関しては, ヒントになるオブジェクトを置くなどするべきでした。正直, 難易度は理不尽級に高かったものの「どうせ解かれるでしょ」と思っていたら1人にしか解かれていなかったので*1やってしまったなと後悔しました。逆に, もう一方の問題は, ヒントとなるオブジェクトがあったためか, 6割程度の方が解けていました。 そのため, OSINT問題は事前に友人に出題してみて, 特定できるかを確認してから出題するのが良いと思いました。

一方で, Grass FlagCaesar Cipher Translatorの二問はまぁまぁ面白い問題だったと自負しているので, そこは良かったと思います。 実際にアンケートでも面白かったというコメントをいくつもいただけたので良かったです。

来年はこれらの謎問題を含まないようなCTFにするので, もしよければ来年は参加してみてください。

Goが楽しい

昨年はGoを一番使いましたし, 今後のメイン言語をGoにしようと思うほどGoを書いた年でした。 ここまでハマるきっかけとなったのは, 一昨年2月ごろに開催されたMercariさんのStep up goでした。ここで, 毎週Goについて実践的に学ぶことが出来たので, 自信が付いてゴリゴリ書くようになりました。

Goの良さは色々ありますが, 私が最初に惹かれたのはエラーハンドリングでした。
他の言語ではtry-catch-finally形式の例外処理機構を用いるものもありますが, 私はこれがあまり好きでないです。 別に悪くはないのですが, とりあえずExceptionなら弾くのが気持ち悪い, とか, スコープが異なるので事前にインスタンスを宣言しておく書き方が気持ち悪い, とか, そういった理由で好きではないです。その点, Goは標準的にエラーを戻り値として取得する週間がありますし, finally句の代用としてdefer句を使用することで絶対に処理したい部分を簡素に書くことが出来ます。

他にも, 平行処理に対するサポートや実行効率が良く, 静的解析しやすいところも良いところでしょう。実際に, 先日のSpecification輪読会で, 「interfaceのアドレスはいつ確保されるのか」という話が出た時に, 気軽にバイナリを解析できました。

このような流れで, 来年もGoを積極的に使っていくことになると思います。 最近はGo Language Specification輪読会でSpecificationを読んでいるのですが, 知らなかった仕様に驚き学ぶ日々を送っています。新年は1/13に開催するので興味のある方は参加してみてはいかがでしょうか。

Rustも良いらしいですが, 沼に落としてくれる人がいなかったので, そういった方が出てきてくれればぜひぜひ沼に引きずりこんで欲しいところです。よろしくお願いします。

研究が大変

これが一番苦労した(している)ところです。 その原因は, 問題設定とその解決法の2つにあると考えています。

まず, 問題設定に関して。 今までは問題が既に設定されていて, それを解決するという道筋でした。 学校で出題される問題や, 競プロ, CTF, 技術検証でもこれは同じです。そのため, これらは情報収集をすることで外堀を埋めて地道に理解していけば解決できることが多いと考えています。

しかし, 研究では問題を定義するところから始まります。この問題設定が確実に正しいかは分かりません。例えば, 設定した問題を解決する手法が時間計算量的に渋かったり, そもそも別部門で議論されていたりすることはよくあるのです。そのため, お偉い教授に相談してから問題設定がマズいと指摘されることがありました。この原因は, 一言で言えば僕の情報不足によるものなのだと思います。この情報不足に対して, クリティカルに効く文献などは無いので, ひとまず有識者に相談することがベストだと思っています。とはいえ, 有識者もヒマではないのでここで作業を続けた結果, 出戻りが発生することが多かったです。もっと良い対処法があればご教授いただきたいです。

次に, 解決法に関して。 解決(できる可能性のある手)法はたくさんあります。その全てに取り組むことは時間的に厳しいので, 最初にある程度調査を行った上で解決法を試す必要があると思います。 が, 僕は引き際を見誤り, 解決できそうな手法をひたすら試してしまい, 時間を棒に振ってしまいました。今思えば良くなかったと思いますが, 当時はもう少しで出来ると本気で思っていたので悲しいです。これに関する対処法は時間を決めて取り組むことなのか, 単に僕の能力が低かったのかよく分かりません。

教育実習で得られたもの

今年の10月中旬から11月上旬にかけて, 母校にて3週間だけ数学の授業を32時間分実習させていただきました。 昨年の介護等体験では, どのような相手に対しても等しく対応することの重要性を再確認したと書きました。

今回の教育実習でも多くのことを学ばせていただきました。その中で, 1つ挙げるとすれば時間の管理方法だと思います。端的に言うと, 期限がギリギリである程度の質を求められた時にどう対処するか, を実践を通して学ばせていただきました。

僕なりの答えとしては, 自分で時間的な期限を決め, その7割を超えた時点で収束に持ち込むという方法がしっくりきました。 これは授業においても, 授業外に関してもそうでした。

きっかけは, 授業用の指導案と実際に行う授業の進行がズレてしまい, 時間通りに終わらせるためのアドバイスを先生方からいただいたことでした。
その内容をざっくり書くと下記の通りです。

  • 指導案はあくまで目安に過ぎない
    • 教育実習の建前として作らせているだけ
  • 実際の授業では残り15分を境に教える範囲を進めるか復習するか決めている

これを受けて実践してみると, 意外と上手く行きました。残り時間が少なくなった時は授業の復習時間に充てることで生徒の理解度向上にも寄与した気がしますし, 何より指導案通りにいかない可能性を視野に入れて授業を出来たので, 最初の35分間をのびのびと使うことが出来ました。

さらに, 授業外でもこれが使えることが分かりました。というのも, 私の実習では32時間分担当するということを, 実習初日に知らされ, 初回授業が実習3日目だったものですから, 全ての資料作成が当然間に合いませんでした。 そのため, 次の授業の資料作成を前の日にやるというのを繰り返した結果, 初週の平均睡眠時間が1.5hという結果になってしまいました。 このままだと2,3週目にぶっ倒れると思い, 対策を考えていた矢先, 先ほどの「残り15分を境に決める」という言葉をふと思い出しました。 50分授業で残り15分というと, 開始から35分後なので全体の7割にあたります。 これを, 翌日の資料作成においても実践してみると睡眠時間を最低限確保した上で資料作成に取り組むことができるのではないかと考えました。 結果として, これにのっとり, 2,3週目は安定した睡眠時間を確保した上でそこそこの授業を実施出来たと思います。

これは僕だけかもしれませんが, 完璧主義寄りの人は睡眠時間を犠牲にしてまで何かに取り組みがちだと思っています。 その結果, 体調を崩したり課題ごとの質がバラバラだったりすることがあるのではないでしょうか。 しかし, それを改善しなくてはいけないとわかっていても対策が分かっていない方もいると思うので, 参考になれば幸いです。

他にも, 先生方を観察していると, 不器用にも全力でやっている先生方もいらっしゃいましたが, 上手いこと手を抜けるところは抜いて職務にあたっている方もいらっしゃいました。 もちろん良し悪しは付けられませんが, 出来れば僕は後者でありたいなと強く思ったそんな教育実習でした。

他にもエピソードはあるのですが, 全部書いてしまうとつまらないので, 対面でお会いしたときにでも機会があればお話しましょう。

SecHack365の途中経過

SecHack365は, セキュリティ・キャンプで存在を知り応募しました。

僕は研究駆動コースだったので, 下記の3点を鮮明にして応募要項を埋めました。

  • どんな研究を志望するのか
  • SecHack365がなぜ必要なのか
  • 研究のために何を今しているのか

現状で, 周りのプロたちよりは成果が出ていませんが, そもそもこの環境にいられたこと, そしてトレイニー同士のつながりを作れたのが大きな成果です。
セキュリティ・キャンプやインターンでもそうなのですが, 一緒に課題に取り組む方々って良い人ばかりなんですよね。 先述したCTFでサーバをHackしてバースデーメッセージを載せてくる人や, 他のトレイニーが取り組んでいる課題に対してアドバイスや意見を飛ばしてくださる人, ギークな話題で語りあえる人などなど, 尊敬できる一面を数多く備えている気がします。 こういった環境で切磋琢磨できて僕は本当に幸せだと思います。

しかし, 現実では僕の進捗は微妙なところなので, 残りの2週間で計画と実践をやっていき, なんとか形にしたいと思います。
SecHackは終わりではなく始まりなので, 今後の研究において大きな転機となったのは間違いないです。

2021年の目標

  • 積極的にインターンに申し込む
  • 査読付き論文を1本通す
  • 朝活を継続する

この3つが, 今年達成したい3つの目標です。昨年は5つにしていたのですが, 今年は変化がありそうな年なので余裕を持たせて3つにしました。

おわりに

以上が, 2020年の振り返りと2021年の目標でした。

2020年は予想とは異なる年になってしまいましたが, 今年は着実に一歩一歩進んでいくつもりです。

長くなってしまいましたが, ここまでお読みいただきありがとうございました。少しでもためになる部分があれば幸いです。 では, 今年も1年よろしくお願いします。

*1:1人解いていた人は朝の4時ごろまでずっとやっていたようです......一体どこのOOtokiさんなんだ......