はじめに
こんにちは、はじめまして。東京工業大学大学院情報理工学院修士1年の山本悠眞(Yamamoto Yuma)と申します!
普段は認知神経科学の研究をしている私ですが、今回有難いご縁を頂き、9月20日から6週間LINEの技術職就業型コースのインターンシップに参加してきました。
私は期間中NEWS開発1チームに配属され、案件の一つとして記事をレコメンドするかどうかの判別機能の改修を行いました。この記事では期間中に担当した案件や、LINE NEWS開発の案件を担当した経験を通して学んだことをご紹介していきたいと思います!
内容に入る前に、先に私の開発経験を軽くご説明します。
私は約1年間学生ベンチャーでPHPを使ったWebアプリ開発をしており、そこではスピード感を重視していたために仕様書を書く文化は全くなく、QAチームなどもいない状況でした。そのような中、私は世の中のエンジニアの方々が実際にどのようにプロダクトを開発しているのかを知りたいと思うようになり、特に以下の2点について知りたいと思い、今回インターンに参加させて頂きました。
- 大規模プロダクトにおける案件の進行フロー
- 一週間のエンジニアの過ごし方
このような訳で、エンジニアってどのように仕事をしているんだろうとか思っている学生さんにはお役に立てる記事にしようと考えていますので、エンジニアに興味がある人もない人も是非ご一読いただけると幸いです!それでは内容に入っていきたいと思います!!
案件(レコメンドロジックの改修)について
内容とその背景
皆さんはこちらのLINE NEWSを普段ご覧になるでしょうか。
ご覧になる方は画像内上部のようにおすすめ記事が横並びに掲載されていることをご存じかもしれませんし、普段ご覧にならない方もLINEアプリの左から2番目に表示されるChatsタブ(トークタブ)から表示できるトーク一覧の最上部におすすめの記事が掲載されているのを見たことがあるのではと思います。LINE NEWSでは全ての記事に対して、レコメンドしても問題ないかを判別しており、例えば不適切な表現を使用している記事はおすすめ欄に表示されないようにシステムで管理されています。今回はこの一部のシステムをレコメンドロジックと呼んでおり、これがLINE NEWSのレコメンドの仕組み全体ではないことをご承知して頂ければと思います。
これまではレコメンドロジックに設定できる条件の数が少なく制限が厳しすぎたために、条件によっては本来なら問題ない記事もレコメンドされないケースが発生していました。そこで今回の案件の背景として、適用させる条件を従来のものより細分化し、それらを別々に使う、または組み合わせることでより適切なレコメンドを行えるようにしたいという要望がありました。
ここで余談ですが、どのようにレコメンド判定しているのか気になる方もいるのではないでしょうか。これには「Kuromoji」という日本語の形態素解析エンジンを用いて記事の内容を解析した結果と、予め登録してある記事フィルタの条件を利用してレコメンド対象とするかどうかを判定しています。自然言語処理を専門にされている方はご存じかもしれませんが、Kuromojiは日本語文を形態素と呼ばれる単語に分割し、それぞれに対して基本形や品詞のタグ付けなどを行える素晴らしいオープンソースコードです。私はKuromojiを今回初めて知ったのですが、今後自然言語処理をする機会がありましたらこれを使おうと思いました!
設計
今回の改修したレコメンドのロジックは以下の図の通りです。記事が作成・更新されるとそれはデータベースAに保存されますが、それと同時に記事がフィルターにかけられます。そしてフィルターに引っかかる記事はレコメンドしない記事として追加で別のデータベースA'にも記録されます。今回の案件では記事フィルターに元々あった「旧レコメンド判定条件」を「新規レコメンド判定条件1」と「新規レコメンド判定条件2」に分割しました。
この案件の実装範囲は以下のようにまとめられます。
- 記事フィルター
- 新規条件追加に伴うデータベース構築
- 条件の適用を制御する管理画面の改修
- 管理画面のUI変更
- 既存APIの変更・新規APIの作成
以上それぞれの設計を誰にでも伝わるように仕様書に書き起こします。仕様書を書くこと自体が初めてでしたのでメンターさんにレビューして頂きながら、使ったことのないツールを積極的に活用しつつ進めていきました。その中でPlantUMLというツールを扱ったのですが、こちらはデータベースのUMLをコードで表すことができ、細かい変更を加えても自動で見た目の修正をしてくれるという便利なツールでした。ただ、drow.ioのような図を直接描くようなツールと派閥が分かれそうに感じました!
またAPIの定義も初めてで、例えば必要なデータをAPIを通して効率的に返すためにどのように設計を行い、どうJSONの形式に落とし込むかの方法を実践できたため、この設計段階から既に非常に良い経験ができていると感じていました。
実装
初めてのJavaかつ初めてのSpring Bootでした。私はPHPのLaravelを主に用いた開発経験しかなかったため、特にアノテーションを付与する仕様には慣れが必要でした。とはいえアーキテクチャの考え方においてもコントローラークラスがあり、サービスクラスがあり、モデルを定義するクラスがあったりと自分が知っていた考え方に似ている部分も多かったため、なんとか対応できたのではないかと思っています。
ロジックの実装およびその方針
新しく発見したところを挙げるとドメイン(業務領域)に焦点を当てて実装が行われることにより、ビジネスロジックの共通部分を抜き出すことができ、それにより再利用が容易になるということを学びました。これは馴染みが薄かったですが、理に適っている考え方だと思いましたし、今回自分のものにできたように感じます。他にもデータベースとデータのやりとりをするDAOやRepositoryの考え方・実装方法はこれまでの自分にないものだったので、非常に勉強になりました。ちなみにこれらを書いているときもアノテーションは頻出でした。
テストコードの実装
初めてテストコード(UT・IT)を書きました!これに関しては本当に知識がありませんでしたが、なんとか自分だけでテストコードを記述できるようになりました。モックの考え方が出てきましたが、その際にモックの記述内容を省略するためできるだけテスト対象となる処理部分を静的な関数にすることを意識しました。静的にすることで処理の依存を減らし、入力と出力だけを検証すれば良くなるのでテストコードを簡潔に記述することができるのです。こちらは特に良い経験になり、勉強になりました。学校の友人にテスト駆動開発は良いよとお薦めされていたのですが、今回テストを書いてみた結果、その魅力が少しわかったような気がします。テストが通らなければエラー箇所を教えてくれますし、通れば通ったで嬉しいですよね。
管理画面とAPIの実装
その他の実装について行ったことを補足的にご説明します。管理画面のフロント部分はVue.jsを使っており、こちらは私が未経験なこともあって同じチームの方が実装をしてくださいました。APIについては時間の関係上、私は一部分のみを担当しましたが、データベースアクセスの際にキャッシュを導入することでアクセス回数を抑え、負荷軽減・応答時間高速化の実装をするなど新たな経験を得ることができました。
ここまでで、案件そのものに関してのご紹介は区切らせていただきます。次はこの案件の進行フローをご紹介します。
案件の進行フロー
LINE NEWSのバックエンドのエンジニアがどのように案件を処理していくのか。それを6週間の中でしっかりと体験してきましたので、エンジニアってどのように仕事をしているんだろうと思われている学生さんなどに役立てるよう、この章を書いていきます!
まずは私の過ごし方を共有します。インターン生である私が主に案件を扱っていたため、社員さんよりもかなりルーズな時間の使い方をしています。現役の社員さんなら倍以上速いです!
あとこれは本当にどうでもいい話ですが、本期間はシルバーウィークに重なったり、祝日が多かったりなどで実質的に働けた期間が少ないように感じました。(勿体無い!)
ちなみに5週目より先で進捗が消失している理由は、ブログを5週目に執筆しているからです。
キックオフ
今回は上記の案件を企画さんから頂きました。LINE NEWSの開発では実はその中でもUIT(フロントエンド)・SERVER・QA(Quality Assurance)のロールから構成されるスモールチームに分かれており、案件はスモールチームの単位で扱います。なので案件を頂く前に定例のアサイン会で案件がスモールチームにアサインされ、そこでその案件を扱えるのかが決まります。
そして案件の内容に目を通し、その後認識の確認や全体スケジュールに認識を揃えるためにキックオフと呼ばれる会議をします。恐らく皆さんの直感的な理解で相違ないと思います!
設計 & 仕様書の作成
次のステップでは設計をし、仕様書を作成します。LINEのような大規模なサービスでは仕様書を書く文化がしっかりと根付いており、社内 Confluenceとして仕様書に限らず多くの情報が管理されています。
仕様書では以下の点が重要です。(細かい部分は省略しています。)
- 誰が案件に関わっているのか
- 機能の要件・機能を実装する理由
- 必要要件
- 全体デザインの概観
- デザイン詳細
- DB設計
- ロジックの設計
- APIの仕様
- etc...
設計段階で仕様書をしっかりと書くことは大切ですが、アジャイル開発の都合上、仕様の調整やステークホルダーのレビューを取り入れることが多々あります。その結果細かい設計の変更が生じる事もあるので、ウォーターフォール開発とは違いはじめから完璧なものは求められないようです。該当箇所のコードリーディングをしながら設計を行うのでそれなりに時間がかかりますが、誰が読んでもわかるように仕様書を書いていきます。仕様書が完成したらSlackの開発者チャンネルでレビュー依頼を出します。基本的にはレビューを頂いて修正した後、実装段階に移ります。
実装 & コードレビュー
こちら基本的には仕様書にある設計とLINE NEWSの実装方針に従って実装を行います。実装後はテストコードを作成します。どのようなテストを作成するのかは実装者に任されており、境界値分析などを軸として網羅的にテストが作成されていれば問題ないようです。作成したテストケースがパスするようになったら、かつ動作テストを通ったらSlackの開発者チャンネルにレビュー依頼を出します。
Beta Up & QAチームによる指摘対応
実装が完了するとBeta環境にデプロイされ、QAチームの方々が動作確認などを隅々まで行なってくださいます。Beta Up後はそこで見つけてくださったバグなどを修正する期間になります。ただここで見つかるような難しいバグは私では手に余るので、この時点で当ブログを執筆しております。もちろん、レビューでどんな修正がなされているのかはしっかりと確認しています!
私も社員さんのようにスマートにバグを解決できるようになるため努力しなければと思う今日この頃です。
LINE NEWSのアジャイル手法
案件の処理フローは上記の通りですが、まだ紹介できていないLINE NEWSでのアジャイル開発に関しまして通常一週間の予定の立て方、タスクの割り振りの仕方などを少しだけここで述べます!
LINE NEWSでは一般的なアジャイル手法をチームに合うようにアレンジして運用しています。
まず月曜日にRefinementやSprint Planningと呼ばれるミーティングを行い、その一週間(スプリント)で扱うタスクを決めます。そのタスクは前週からキャリーオーバーされたものや、新しく取り組む案件のものなど様々です。それぞれのタスクにはポイントと呼ばれるタスクの重さのようなものが設定されており(厳密にはそれぞれのロールの方々がポイントを定義します。)、QAチームの方々やエンジニアの方々が一週間のうちで自分らの処理できるポイントを確認しつつタスクを決めるため、過度なタスクが割り振られることが無いようになっています。
火曜日、水曜日、木曜日はいくつかの会議に参加しながらも基本的には担当のタスクを消化していきます。それぞれの日の最後にはDaily Scrumと呼ばれる短時間のミーティングを行い、進捗を報告します。
金曜日はSprint Reviewでそのスプリントでの成果物をレビューしたり、Sprint Retrospectiveというスプリント全体の振り返りをしたり、先ほど述べたような新規案件のアサイン会があったりなどミーティングが多くあります。
以上のように一週間が過ぎて行きます。
非常にざっくりとした説明ではありますが、イメージは湧きましたでしょうか?
終わりに
前半は案件そのものについて述べつつ、後半は案件処理の一連の流れを紹介させてもらいました。
まずは今回のインターンでメンターについてくださった東山さんに感謝を申し上げます。また毎日デイリースクラムに参加してアドバイスをくださった齋藤さんやスアルタさんもありがとうございました。他にも今回のインターンに関わってくださった全ての方に感謝を申し上げます!
思い返してみると本当に充実した6週間であったと思います。ベンチャーでの開発経験しかなかった私がやってみたかった「大規模な開発」に携わることもできましたし、何よりLINEのバックエンドエンジニアとして働くというリアルなイメージを掴むことができたことが一番の収穫であったと考えています。
このインターンで学んだことを糧に今後の開発やエンジニア生活に活かしていきたいと考えております!
エンジニアに興味のある全ての学生さんに、このインターンは自信を持ってお薦めできます!!
以上です。ここまで読んでくださり、ありがとうございました!
(これはブラウン君と四谷のオフィスで仕事をした時の写真です。)
参考文献
- kuromoji