エンジニア全体ミーティング Tech MTGのすゝめ

こんにちは。投稿開発部エンジニアの土谷(@taihaku0415)です。 Androidアプリcookpad.comの開発を中心に担当しています。

現在、クックパッドには100人弱のエンジニアが在籍しています。普段エンジニアはそれぞれの事業部に所属して、業務を行っています。スマートフォンアプリを専門に書くエンジニア、広告領域を担当するエンジニア、インフラや開発の基盤を構築しているエンジニアなど、多岐に渡ります。 そのため、クックパッドでは、業務をする上で必須なものから、他のチームの開発の知見や生産性を上げるためのtips(ツールの紹介や使い方など)まで、様々な情報を共有して、開発力や技術力の向上に役立てるための取り組みを行っています。

例えば、技術領域課題共有会では各部署・チームの課題を話し合う場が設けてあります。また、Groupadという社内ブログサービス上で、全社員(エンジニアにかぎらず全ての社員)が気軽に情報を発信しています。 それ以外にも、クックパッドの全てのエンジニアが顔を合わせて集まるエンジニア全体ミーティング、通称 Tech MTG を行っています。*1

今回の記事では、私も企画・運営に携わっているこのTech MTGに関してご紹介します。

Tech MTGとは

f:id:slippyvalley:20160916172744j:plain

クックパッドでは日本のオフィスにいる全てのエンジニアが集まって情報共有する機会を隔週で30分程度設けており、企画、運営もエンジニア自身で行っています。

なぜやっているか

目的

Tech MTGの主な目的はエンジニア全体での 情報共有 です。

具体的には

  • 社内外で今話題の技術トピック
    • RubyKaigiやGoogle I/Oなどのカンファレンスの参加報告も含む
  • 新機能やサービスのリリース後の話
  • 事務的な連絡事項(e.g. 社内のインフラやツールに関する変更や、全エンジニアが知っておくべき周知事項)

を中心に各開発を担当しているエンジニアに発表してもらう、ということをしています。 また、人事部長や開発本部長から、今後のクックパッドのエンジニアリングの方向性についての発表もあります。 Tech MTGでは、開発担当者からサービスや機能の実際について生の声が聞け、質疑応答がその場でできます。

Tech MTGではなにが話されてるのか

では、Tech MTGではどんなことが話されているのでしょうか。ここではほんの一部ですが過去のTech MTGで発表された内容を紹介します。

Job Queue Systemに関する話

クックパッドのJob Queue SystemであるBarbequeについての発表がありました。このBarbequeについては、先日のRubyKaigi 2016でも開発担当者の国分が(@k0kubun)が発表しました。社内では、Barbequeが使えるようになった時に発表され、本格的に運用する前だったこともあり設計上の問題点についても他のエンジニアから指摘が入っていました。

speakerdeck.com

資料: https://speakerdeck.com/k0kubun/scalable-job-queue-system-built-with-docker

クックパッドのMicroservicesへの取り組みに関する話

クックパッドで取り組んでいるMicroservicesの事例に関して、社内で行われている様々な取り組みの事例もあげて説明してもらいました。詳しい内容はクックパッドにおける最近のMicroservices事例 でも紹介されています。

speakerdeck.com

資料: https://speakerdeck.com/adorechic/how-microservices-are-linked-at-cookpad

Google I/Oの参加報告

社内の技術的取り組みに関する話以外にも、Google I/O 2016に参加したAndroidエンジニアに、Keynoteで気になった発表の内容を選んで説明してもらったり、サンフランシスコ・ベイエリアのスタートアップ系の企業に訪問して交流した話を紹介してもらいました。このように大きなカンファレンスの参加報告をしてもらうこともあります。

技術顧問によるテストの話

また、クックパッドの技術顧問の一人である@t_wadaさんにテストに関しての発表をお願いしたこともあります。その後TDD Bootcampというテスト駆動開発の勉強会も開催しました(参考: テストを使いサービス開発を駆動していくために取り組んでいること)。

法務部の社員からの話

発表の内容は、必ずしもエンジニアリングに関するトピックに限りません。
先日のTech MTGでは、法務担当の社員から、全てのエンジニアが知っておくべき法律についての発表がありました。

このように、Tech MTGでは技術的な話を中心に幅広いテーマを取り扱っています。

どのように運営されているのか

Tech MTGは、これまでは社内の有志数名によって運営されていましたが、今年の1月から技術本部長の成田 (@mirakui)と新卒2年目のエンジニアが中心になって行っています。

定例ミーティング(Tech MTG MTG)

Tech MTGがあった日に運営メンバーで集まって、振り返りと次回以降の発表内容の確認・検討を行っており、口頭で話した内容を、GitHubのIssueを利用してドキュメントに残していく方法でミーティングを進めています。 ミーティングでは、毎回同じアジェンダのテンプレートを使って各項目にチェックし、Tech MTGの準備に抜け漏れがないようにしています。

f:id:slippyvalley:20160916172847p:plain ※定例ミーティングで使用しているアジェンダ(チェック項目)

振り返りでは、KPT (Keep, Problem, Try) フレームワークを使って振り返り行い、Problemで挙がった問題点を改善するためにTryの内容をissueに書き込んで次回改善されていたら閉じる、というように地道な作業をしています。

f:id:slippyvalley:20160916185310p:plain

また、準備期間をしっかりとれるように、約一ヶ月前には企画を固めて登壇者に依頼しています。 大きな機能のリリースや社内外のイベントに参加した社員(カンファレンスへの参加、社内勉強会など)がいないか、最近技術的にホットな話題とそれに精通している社員がいないか等から運営メンバー間でネタを出し合って、その中から多くの社員が興味を持ちそうで、業務にも役立つものを選んでいます。

まとめ

クックパッドのエンジニア全体ミーティング Tech MTGの目的、発表内容、どのように運営しているかについて紹介しました。 参加するエンジニアには業務時間を使って30分程度集まってもらい、登壇をお願いしている社員も準備に時間を割いてくれています。 なので、今後もTech MTGの登壇者・参加者が参加してよかったと思える、そんな情報共有の場にしていきたいと思っています。

最後になりますが、クックパッドではエンジニアを募集していますので、興味のある方は募集一覧をみていただくか、気軽に@taihaku0415までご連絡ください。

*1:ディレクターの知見共有会というのもあります

ECS を利用したオフラインジョブの実行環境

技術部の鈴木 (id:eagletmt) です。 クックパッドでは以前からアプリケーションの実行環境として Docker を利用していましたが、最近は徐々に Amazon EC2 Container Service (ECS) を利用し始めています。 去年の時点での Web アプリケーションのデプロイ手法 *1 や、最近 ECS を利用してどう Web アプリケーションをデプロイしているか *2 については紹介したことがあるので、今回は定期的なバッチ処理やジョブキューを介して非同期に実行されるようなオフラインの処理について、どのような環境を構築しているか紹介したいと思います。

Docker を使う前

Docker を利用し始めるより前から社内では kuroko2 *3 というジョブ管理システムが稼動しており、複数のアプリケーションから利用されていました。 kuroko2 は定期的にジョブを実行するために必要な機能を十分そなえている一方で、複数のアプリケーション向けにワーカインスタンスをプロビジョニングする必要があること、ジョブを実行するワーカを柔軟に増減できないこと、といった欠点がありました。

Docker の導入

Docker を利用することにより、複数のアプリケーションから共通で使われつつもインスタンス側に必要なプロビジョニングを最低限に抑えることができるようになりました。 インスタンス側の構成はシンプルになり、新しくアプリケーションを追加するときに必要な手間も非常に小さく済みます。 プロビジョニングの手間だけでなく、API キーやパスワードのような秘匿すべきクレデンシャルがインスタンスに直接置かれることを防ぎ、ワーカインスタンスのインスタンスプロファイルにすべてのアプリケーションに必要な権限をつける必要がなくなり、共通のインスタンスを複数のアプリケーションで使い回しつつも権限が適切に分離できるようになりました。

社内では定期的なジョブを実行するときは kuroko2 を使うのが標準となっていたため、kuroko2 から Docker を利用するための機能追加やインスタンスの整備なども行いました。 これにより Web アプリケーションを動かすための Docker イメージを作ってあれば自動的に kuroko2 で実行する環境も手に入るようになり、アプリケーション開発者にとってオフラインのジョブ実行をする際の障壁が大きく軽減されました。

ECS の導入

Web アプリケーションのデプロイに ECS を利用し始めたのと同時に、オフラインジョブの実行にも ECS を利用し始めました。 Web アプリケーションのデプロイに使っているツールである hako を使って、kuroko2 から hako oneshot awesome-app.yml -- bundle exec rake some:heavy:task のようなコマンドを実行するようにしています。 hako oneshot は YAML の定義に従って ECS の RunTask API を呼び出すコマンドで、オフラインのジョブや bin/rails db:migrate のような単発のコマンドを実行するために使います。

直接 Docker を使っていたときと比較してよくなった点の一つに IAM ロールを利用できるようになったことがあります。 ECS ではインスタンス単位ではなくタスク単位で IAM ロールを利用でき、これにより AWS のアクセスキーを発行することなく AWS の API を利用したジョブを実行できるようになりました。

ジョブキューからの利用

先日の RubyKaigi 2016 で紹介されたように、現在 barbeque というジョブキューのしくみが整備されています。 barbeque からジョブを実行するときには社内では hako oneshot が使われています。 https://speakerdeck.com/k0kubun/scalable-job-queue-system-built-with-docker

barbeque へのエンキューは Web アプリケーションへのリクエスト起因であることが多いため、ジョブの実行回数、つまりジョブの実行に必要なリソースを事前に予想することが難しく、また時間帯によって刻々と変化するという特徴があります。 したがって、常に安定的にジョブを実行しつつコストを抑えるためには、オートスケールが重要になってきます。

オートスケーリング

ECS の導入によって、ワーカインスタンスのスケーリングが容易になりました。 ワーカインスタンスとして使うための ECS クラスタを作成し、そのクラスタのインスタンスはすべて AutoScaling グループで管理するようにしました。 hako oneshot は RunTask API を使っていますが、この API はもし実行に必要なリソースがクラスタ内に不足していた場合にリソース不足を知らせるエラーを返すので、そのエラーが発生した場合は AutoScaling グループの desired capacity を引き上げ、再度実行を試みるようにしています。 この挙動は hako の定義ファイルで autoscaling_group_for_oneshot に AutoScaling グループを指定することで有効化できます。 https://github.com/eagletmt/hako/blob/v0.20.0/examples/hello-autoscaling-group.yml

一方、スケールインの実行は CloudWatch のメトリクスを定期的にチェックすることで行っています。 ECS はクラスタ毎にどれくらい CPU、メモリが使われているかの割合を自動的に CloudWatch に保存しているため、直近の実績値を参照することで現在必要なリソース量を見積もることができます。 クラスタが提供するリソースのうち P % を利用しているような状況を維持したい場合、現在のインスタンス数を N とすると n 台減らせるかどうかの閾値は (N - n) * 100 / N * P になります。 リソース量の見積もりと閾値の計算を毎時実行し、見積もりが閾値を下回っていたら AutoScaling グループの desired capacity を下げることでスケールインを実現しています。

スケールインするときには、実行中のタスクが中断されないように注意しなければなりません。 AutoScaling にはライフサイクルフックというしくみがあり、AutoScaling によってあるインスタンスが terminating 状態になってから実際に terminate されるまでの間に終了処理を行えるようになっています。 ライフサイクルフックによって terminate が決定したときは AWS Lambda 経由でそのインスタンスに特別なタグをつけるようにしています。 各インスタンスは定期的に自分自身のタグをチェックし、もし特殊なタグがついていれば自分自身を DeregisterContainerInstance してサービスアウトし、その後ライフサイクルを継続させます。 もしそのインスタンス内でタスクが実行中であれば DeregisterContainerInstance は失敗するので、成功するまで DeregisterContainerInstance を実行し続けるようにしています。

今後の課題

ECS を利用しているとコンテナインスタンスのスケールアウトはしやすい一方で、スケールインをするには現状いくつかの工夫が必要になっています。 比較的短時間で終了するタスク専用のクラスタであれば DeregisterContainerInstance を成功するまで叩き続けるという方法でスケールインできるようになりましたが、 長時間実行が続くようなタスクが実行されてる場合や ECS の service を使っている場合など、すべての場合で自動的にスケールインすることはまだできていません。 このようなケースでもスケールインする方法を考える必要があります。

また、スケールアウトをするタイミングが現状は実際にリソースが不足したときになっており、一時的にジョブの実行が遅れることになります。 AutoScaling グループの desired capacity を変えてからインスタンスが起動してコンテナインスタンスとして登録されるまで3分ほどかかっています。 ジョブの実行ができるだけ遅れないようにするためには、インスタンスの起動を高速化する他に、リソースの使用状況の履歴から必要そうなときにあらかじめスケールアウトしておく方法があります。 しばらくはどういう状況のときに実際にリソースが不足してスケールアウトしているかを観察し、その結果をもとにスケールアウトする基準をどうするかを決めようと考えています。

まとめ

Docker や ECS をオフラインのジョブで利用するメリットと、実際にどう利用しているかについて紹介しました。 今後も ECS 自体の改善を注視しつつ、アプリケーション実行環境の利便性を高めながらもできるだけコストを抑えられるように改善していきたいと思っています。

インターンシップ「サービス開発演習」の舞台裏

f:id:ryokatsuma:20160817121332j:plain

こんにちは、投稿開発部副部長の勝間(@ryo_katsuma)です。 普段はクックパッドのレシピ投稿周辺のサービス開発を行う部署のマネジメントやエンジニアリングを担当しています。

さて、クックパッドでは、8月10日から先日9月2日まで技術インターンシップを開催していました。 講義全体のまとめについては、先日公開されましたこちらの記事を参照ください。

今回は、私が担当した4日目の講義「サービス開発」について、どのような狙いを持って設計したか、また参加学生の皆さんがどのような反応だったかなど、舞台裏についてご紹介いたします。

昨年の振り返りと課題

技術インターンシップにおいて、サービス開発の講義は昨年度も私が担当しました。 昨年度は日程の都合上、半日で「クックパッドにおけるサービス開発の考え方についての講義を行った後に、その実践編としてあるお題に対して仮説を立て、企画をまとめる」というかなりコンパクトな内容にする必要がありました。

学生の皆さんにとっては「企画をまとめる」という、普段は行わないような発想をする体験を提供できたかと思いますが、「とりあえず仮説をまとめる」に留まってしまったため、周囲からのフィードバックを得るということはできませんでした。 言い換えると、サービス開発におけるPDCAのサイクルを回す (= LeanStartup的に言うとBMLループを回す)まで体験できなかったので、学生の皆さんにとってやや消化不良な形になってしまったのは反省すべき点でした。

全体設計

昨年度の反省を元に、今年度のトライとして

  • 半日では時間が短すぎるので、最初のインターンシップ全体の設計から関わり、1日の枠を確保する
  • BMLループを少なくとも1周回すことを実現する

をテーマに設定しました。 また、このタイミングで、デザイナの倉光(*1)にも参加してもらい、主に2人で全体設計と当日の運営を進めていくことにしました。

フォーカスすべきポイント

設計を進める上で、あれもこれも、、とやりたいことは多くありますが、インターンの時間は有限なので、フォーカスすべき点は何か?を明確化する必要があります。 そこで昨年度の課題を元に議論を進めていきました。

正解は誰にも分からない

参加学生に最も理解してもらたいことは、サービス開発において「正解は誰にも分からない」ということです。講義を行っている自分たちはもちろん、社長ですら「何がユーザーに受け入れられるものか」は究極的には分かりません。そのためにも早く小さな価値ある失敗して、そこから学びを得て正解を探る必要があります。

動くものでユーザーの声を聞く

価値ある失敗から学びを得るためには、ターゲットユーザーから仮説検証を行うプロダクトの利用ログを分析する必要がありますが、そのためには1日で実装から本番環境にデプロイまで行うのはさすがに現実的ではありません。そこで、ターゲットユーザーに動くものに触れてもらい、直接意見を聞くことで同等の効果が期待できます。そのためにも、動くもの、つまりプロトタイプを作ることが大事になります。

このような議論を経て、「プロトタイプを元にユーザーインタビューを行う」を今回の演習で最もフォーカスするポイントとして設定することにしました。

どんどん諦める

限られた時間の中で上記の実現すべきことにフォーカスするためにも多くのことを積極的に諦めることにしました。

課題設定をしない

そもそも「誰の何の課題を解決するか」は非常に大事なテーマです。今回もここの領域は是非挑戦してもらいたいところではありますが、今回はここに時間をかけることを諦めます。代わりに、解くべき課題と、それに対する仮説をこちらであらかじめ設定することにしました。

f:id:ryokatsuma:20160905202347p:plain

今回は「子どもがもうすぐxx歳になるお母さんは、誕生日パーティを家族の思い出に残るものにしたいけど、何を作ったらいいか分からない」という課題を解決することを、実習における前提としました。

ちなみに、この課題は

  • 料理の領域に制限することで自分たちもフィードバックを返しやすい
  • 学生たち自身の経験則で進めることはできない
  • 対象ユーザーが社内で確保しやすい

などの理由からこの課題を設定しています。

1人のターゲットユーザー以外を考慮しない

課題が設定されていたとしても、その課題を持つできるだけ多くのユーザーを満足させることを考える時間もありません。

そこで、今回はターゲットユーザーは1人に絞り、ターゲットユーザー以外の人の考慮はしないようにしました。

f:id:ryokatsuma:20160905203530p:plain

実際の社内のスタッフをターゲットユーザーに見立て、事実を元にしたペルソナシートを用意することで「誰の課題解決をするか」を把握できる状態を狙っています。

プロトタイプの実装はしない

確保した時間から逆算すると、プロトタイプの準備にかけられる時間は2時間程度のみになることが分かりました。そこで、「エンジニアだからこそ実装しないと」の発想をやめてもらうためにも、InVisionを利用することで「手書きでプロトタイプを作る」という制限を課すことにしました。

f:id:ryokatsuma:20160905203915p:plain

これは今回用意した見本ですが、付箋とペンで描いた絵であっても「オムライスを検索してるんだな」は伝わるかと思います。

画面をいきなり作ることはしない

短期間でプロトタイプを作るとなると、「よくわからないからとりあえずそれっぽい絵を描く」ということになりがちですが、その際、結局「何をしたいかよくわからないもの」に仕上がりがちです。

そこで、今回は「実現したいユーザーストーリーをあらかじめ描き、それを元に絵を描く」という制限を設けました。

f:id:ryokatsuma:20160905204325p:plain

この例は、フリマアプリを利用を使う人のユーザーストーリーをユーザーの言葉で並べたものですが、例えばこのようなプロトタイプを作ることができるでしょう。

演習

事前リハーサル

今回は、事前に学生アルバイトのエンジニア2名を前にして講義の内容を聞いてもらい、画面をつくるためのユーザーストーリーシートも実際に書いてみてもらいました。これによって、伝わりづらかった点、魅力を感じてもらうために必要な点などいくつかの改善点が見つかり、この時点でいくつか改善点も見つかったものの大筋は問題が無さそうなことが確認できたので、安心して当日を迎えることができました。

当日のスケジュール

当日はこのようなタイムスケジュールで進めていきました。

  • 09:30-10:30 講義+全体説明
  • 10:30-12:00 方針決め+プロトタイプ準備
  • 12:00-13:00 昼食
  • 13:00-14:00 インタビュー準備
  • 14:00-14:30 インタビュー実施
  • 14:30-15:00 インタビューを踏まえた改善案まとめ
  • 15:00-16:00 全体発表
  • 16:00-18:30 振り返り

見ていただくと分かる通り、講師側も正直辛さを感じるスケジュールです。 しかし、結果として参加学生の皆さん全グループ時間内にプロトタイプを形にし、インタビューまで完了できていました。学生の皆さんは本当に素晴らしかったと思います。

インタビューを経て

一方で、全グループともプロトタイプはインタビュイーに満足してもらえませんでした。 多くのグループはパーティ料理の献立を簡単に探せるプロトタイプを作っていましたが、

  • 子どもの年齢で食べられるものは決まるので、年齢毎に検索できないと使えない
  • 具体的に調べたいというより、ぼんやりとインスピレーションを得たい
  • プロトタイプは悪くはないけど、使うかと言われると使わない

のような意見をインタビューでもらっていました。

これはサービス開発を長年行っている者の観点だと、一発で最高のプロダクトを作ることができるわけないので、ある意味当然の反応とも見なせます。ただ、参加学生の皆さんにとっては、非常に新鮮な反応だったようで

  • 自分たちでは最高のものができたと思っていても実際は全然受け入れられない
  • たった1人のためのものを作るのすら、全く正解に辿りつけていない

のような感想を持っていたようです。

演習を終えて

議論の活発化

今回、参加学生を見ていて最も印象に残ったことは、インタビューの前後で議論の熱量が大きく増えたことです。 最初は、どのグループも悩みながら半信半疑でプロトタイプを作っている印象でした。一方で、インタビューを通じて自分たちの仮説が持つ問題点がかなり明らかになったことで、どのグループも「どう改善すべきか?」の議論は活発に行われていました。発表会の後は手持ち無沙汰になってしまうことを危惧していましたが、結果としては終了ぎりぎりの時間まで全てのグループがプロトタイプを改良し続けていたのは非常に印象的でした。

評論的なフィードバックが不要に

今回のようなサービス開発系の発表のフィードバックはともすれば評論家のような話をしがちです。しかし、前述の通り、サービス開発における正解はユーザーの反応です。今回も、学生の皆さんは自分たちの課題について自ら気づいてくれることが多く、主催側の自分たちが細かなことを言う必要はほとんどありませんでした。

ゴールを見失いがち

一方、「誕生日パーティを家族の思い出に残るものにしたいけど、何を作ったらいいか分からない」課題を解決するという、そもその研修の目的を多くのグループが忘れてしまっていました。「すばやくパーティ献立を検索する」にフォーカスしてしまい、「家族の思い出に残るパーティを実現する」というゴールを見失った状態でプロトタイプを作ることに必死になっていたようです。(例えば、ゴールを達成するためにはデリバリーを注文することも手段になるはずです)

学生の皆さんへのフィードバックはこの点について言及しましたが、これは自分たちもともすれば陥りやすい罠です。目的から外れ手段に凝り過ぎてしまうことは、自分たちも油断するとよくやってしまいます。個人的には、学生さんたちの様子を見ることで、自分たちのサービス開発のフローを省みるいい機会になりました。

柔軟な発想

そんな中、思い出に残るという観点で「子どもと一緒に作れる」を軸に考えてくれていたグループがありました。

f:id:ryokatsuma:20160906095804p:plain

「パーティレシピを集めるための投稿ユーザーのモチベーションがうまく設計できていないことで、サービスを成立させることが難しそう」という理由で優秀賞には選定せずに「惜しかったで賞」という枠を選定しましたが、発想としては非常に素晴らしいものでした。このように柔軟な発想に出会えることもインターンを主催側の楽しみの1つです。

思ったよりいい感想を持ってもらえた?

今回は手を動かすことが大好きな学生エンジニアからエディタを取り上げることになったので、実施前は受け入れられるかどうか不安がありました。ただ、日報を見てみると

  • インタビューを通じて様々なことを気づくことができた
  • ユーザーが求めているだろうと自分が考えていたものが、インタビューしてみると全く価値がなかったのは衝撃的な体験
  • ここまでユーザーのことを考えたことがなかったので新鮮

など、前のめりなコメントも多く見受けられました。実際、自分たちで考えたものをリアルなユーザーに直接届け、感想を聞くという体験はなかなか得られないものではないかと思います。 また、後半に進んだ学生の中には、サービス開発を行う部署を希望してくれた人も何人もいました。

「サービス開発は難しい」ですが、同時に「だからこそおもしろい」と思ってもらえる機会を少しでも提供できたのかな、と期待しています。

まとめ

2016年度技術インターンシップにおけるサービス開発研修を舞台裏についてふりかえりを行いました。今年は、昨年度の反省を活かして、価値ある失敗を体験してもらうことに徹底的にフォーカスした設計を行いました。 準備はかなり大変でしたが、結果として昨年度の課題の大半は解決され、学生の皆さんにサービス開発の難しさと楽しさの2つの体験を提供できたかと思います。

最後になりますが、クックパッドではデザイナー・エンジニアを募集しています。このようなサービス開発にご興味あるかたは、募集一覧をご覧いただくか、または@ryo_katsumaまでお気軽にお声がけください!

(*1) 倉光はFablicさんと合同でのデザイナ向けイベントの運営や新卒研修でのサービス開発研修の講師を務めるなど、この領域において経験も実績も十分でした。
(*2) 念のため補足しておくと、ここではもちろんコードを書くことを否定しているわけではなく、早く動くものを用意しよう、ということのみを述べています。Webアプリケーションやモバイルアプリも早く形にできる環境であれば、InVisionなどのツールを使うよりも実際に実装したほうが望ましいです。