TECH PLAY

BASE株式会社

BASE株式会社 の技術ブログ

576

はじめに BASE Dept. Product Devにてバックエンドエンジニアをしている オリバ です。 2024年末、弊社のソフトウェアエンジニア(以下、SWE)でSREに興味を持つメンバーを募り、「SREをはじめよう」を題材にした輪読会を実施しました。本記事では、各部・各章の要点を整理し、実践に役立つ知見を共有します。 ※引用元: O'Reilly Japan SREをはじめよう 第1部 SRE入門 この部では、SREの定義やSREの文化のような、SREの概論に触れています。 SREの定義 書籍では、SREを以下で定義しています。 サイトリライアビリティエンジニアリングは、組織がシステム、サービス、製品において 適切なレベルの信頼性を持続的に達成できるよう支援することを目的とした工学分野である。 工学の分野の1つと認識されていますが、情報系の学部出身の弊社社員の中で、工学分野としてのSREという言葉を耳にしたことがある方はいませんでした。もしかすると、将来的に大学の講義でもSREが取り上げられるかもしれません。 また、SREを理解するのに最適な1枚のスライドが紹介されています。 ※引用元: Keys to SRE このスライドはSREの始祖とも言われているBen Treynor Slossが、2014年5月31日のSREconの基調講演で紹介されたスライドです。 私が特に疑問に思ったのは、上から6つ目の Excess Ops work overflows to DEV team です。和訳すると、「余計な運用作業は開発チームにオーバーフローさせる」という意味になり、なぜ運用作業を開発チームにオーバーフローさせるのか輪読会で話し合い、以下の内容で解釈しました。 余計な運用作業があることを意図的に開発チームに気づかせるようにする SREの運用作業は過剰になりがちで、より重要な業務に注力するために、開発チームに一部を委譲する インシデントが起きたときに、SREの中で閉じないようにする DevOpsとSREの関係性 DevOps コードを本番環境にリリースするために何が必要か考えます。 SRE 本番環境を起点に、信頼できる運用を実現するには何をすべきか考えます。 ※引用元: SREの探求 SREの心構え 本書で特に重要とされるSREの心構えとして、以下の4点が挙げられます。 1. フィードバックループを重ねる 信頼性向上の中心となるのは、継続的な改善を可能にするフィードバックループの構築です。 2. 共同作業を重視する SREは、さまざまな分野の同僚と協力しながらシステムの信頼性を向上させます。また、顧客とも信頼性に関する共同作業を行う姿勢が重要です。 3. オーナーシップを持つ 運用するサービスに対して責任を持ち、主体的に取り組みます。 4. 失敗から学ぶ システムのエラーを学習機会と捉え、そこから改善のアイデアを得ます。 SREの文化を醸成する 本書で紹介されているSRE文化を醸成するための取り組みの中で、組織に取り入れやすいと思われるアイデアを以下にまとめました。 1. トイル削減を祝う文化を作る トイル(以下の特徴を持つ繰り返し作業)を削減した取り組みを組織全体で祝う文化を作ります。 手作業である 繰り返される 自動化可能 長期的価値を持たない サービスの成長に比例して増える(O(n)) 2. 「ポストモーテム会」や「デザインドキュメント会」の開催 ポストモーテムとは、インシデント発生後の事後検証プロセスです。インシデントレポートをチーム全体で共有する文化や、振り返りの場を定期的に設けることで、組織的な学びを深められる可能性があります。 3. チーム間のローテーション SWEが一定期間SREチームに参加する「交換留学」を実施することで、SRE文化が組織全体に広がります。弊社でも2025年からこの取り組みを開始する予定です。 SREを提唱する SREを提唱できる力は、組織内外でその存在意義を説明する場面で重要です。例えば、組織のステークホルダーにSREの存在意義を伝え、SREという組織を存在させる場面でも必要ですし、採用活動や転職時には、SREの役割や文化を候補者や採用側と共有し、ギャップを認識することが求められます。 また、他者の経験やストーリーを学ぶことも重要です。本書では、イベントや勉強会への参加が強く推奨されています。私もさっそく、2025年1月26日に開催される SRE Kaigi 2025 への参加申し込みを行いました。 第2部 個人がSREをはじめるには この部では、個人がSREを始めるために必要なスキルや考え方について説明します。 SREになるための準備 SREになるために必要なスキルとして、本書では以下を挙げています。 1. コーディングスキル コーディングスキルはSREにとって不可欠です。システムの構造を深く理解し、潜在的な故障を予測・防止する能力を備えるには、このスキルが求められます。 2. 計算機科学の学位 計算機科学の学位は必須ではありませんが、コーディング経験を通じて同等の知識を習得する必要があります。 3. モノリス、分散システムへの理解 OSやネットワークの仕組みを理解することは、大規模でスケーラブルなシステムの構築に不可欠です。また、近年ではマイクロサービスやマルチリージョン対応などの分散システムを扱うケースが増えています。 4. 統計とデータの可視化 SLI(Service Level Indicator)やSLO(Service Level Objective)で使用されるパーセンタイルの理解には統計学の知識が必要です。輪読会では マンガでわかる統計学 (Ohmsha) という書籍が推薦されていました。 その他、ストーリーテリング、NALSD(非抽象的な大規模システム設計)、レジリエンス工学、性能工学、AI/MLの知識も重要とされています。 肩書きだけの変更はNG 本書では、学生やSWEがSREに転向する方法が述べられていますが、システム管理者やDevOpsメンバー全員の肩書きを単に「SRE」に変更することへの警告も含まれています。 文化的・戦略的・組織的な変革を伴わない肩書きの変更では、SREの本質的なメリットを享受できません コラボレーションモード SREは「あくなき共同作業」によって成り立つと本書では強調されています。 具体例として、SLI/SLOの策定や実施が挙げられます。また、監視業務を通じて顧客の声に耳を傾け、顧客との共同作業も実現しています。 弊社では隔週で「定点観測会」を開催し、BASEのコア機能を洗い出し、SLI/SLOの見直しを行っています。 トイルとの関係を築く SREは、「SREの文化を醸成する」で触れたトイルに継続的に向き合う必要があります。本書では、その理由として以下の3つを挙げています。 1. 美学 トイルは非効率で美しさを欠き、最適化の障害となります。 2. お金 高度なエンジニアをトイルに費やすのではなく、価値を生む仕事に集中させることで、組織のコスト削減に繋がります。 3. 時間の使い方/仕事の満足度 エンジニアはトイルではなく開発業務に時間を使いたいと考えます。過剰なトイルは生産性と満足度を低下させます。 弊社では毎週、有志メンバーによるトリアージ会を開催しています。この会では、SentryやNewRelicのアラートを確認し、解決すべきIssueをタスクとして起票しています。 また、OKRを活用し、目標を達成するためのトイル解消に取り組んでいます。 ※ 参考: OKRを設定する( https://rework.withgoogle.com/jp/guides/set-goals-with-okrs ) 失敗から学ぶ 本書では、失敗から学ぶ方法として、インシデント後のレビューが重要であるとされています。 インシデント後のレビューでは、単なる文書や報告書、アクションリストの作成に留まらず、以下の点を重視することが求められます。 時系列での詳細な記録 インシデントの前後で何が起きたのかを明確に記載します。 プロセスの記述 どのような資料を参照したのか、解決までのプロセスを詳細に説明し、単なる事象の振り返りにとどまらず、将来の予防策や信頼性向上のための具体的な知見を得られます。 また、インシデント後のレビューを行う際には、以下の行動を避けることが重要です。 犯人探し 問題の原因を特定の人物に帰結させることは、生産的な学びや改善にはつながりません。 ヒューマンエラーへの責任転嫁 人間のミスに焦点を当てるだけでは、システム全体の信頼性向上を妨げます。 成功点の無視 問題解決においてうまく機能した点も学びの一部であり、見落とさないことが重要です。 インシデント後のレビューは、失敗からの学びをシステムの改善やプロセスの洗練に結びつけるための重要な手段です。これを適切に活用することで、組織全体の信頼性を向上させることができます。 なぜなぜ分析はアンチパターン 「なぜなぜ分析」は、トヨタグループの創始者である豊田佐吉が考案した手法です。この手法では、事象に対して「なぜ」を繰り返し問い続けることで、根本原因を突き詰めていきます。一般的に、5回「なぜ」を繰り返すと根本的な原因に到達できるとされています。 本書では、「なぜなぜ分析」は特定の事象を深掘りして原因を発見するのには適しているものの、インシデントを理解し、そこから学びを得るためには不十分であると指摘されています。その理由は以下の通りです。 重要な情報を見逃す可能性が高い システム全体の理解を阻害し、部分的な要因に偏りがちになる そのため、「なぜなぜ分析」はインシデント分析においてはアンチパターンとされています。 「なぜ」を繰り返す前に、まずは「何が起こったのか」を詳細に確認し、全体像を把握することが重要です。インシデントのプロセスや影響を全て洗い出すことで、包括的な学びと改善につながります。 第3部 組織がSREをはじめるには この部では、組織がSREの導入に成功するための要因を探っています。 Dickersonの信頼性の階層構造 既存の組織がSREを開始するためのわかりやすいロードマップとして、Dickersonの信頼性の階層構造があります。 これは、元Google社員のMikey Dickersonが、マズローの欲求階段説を引用したものです。 ※引用元: O'Reilly Japan SREをはじめよう p.198 マズローの階層構造と同様に、階層の一番下からはじめて、下の階層が強固になった時点で初めて上の階層に進みます。 1段目の監視/オブザーバビリティに関して、監視ツールやオブザーバビリティプラットフォームを導入している組織がほとんどだとは思いますが、意外とSLI/SLOまでしっかり実践している組織は少ないかもしれません。 SREを組織に組み込む 本書では、SREを0からスケールアップする(本書ではSRE0と呼ぶ)ために必要なものは、建築工学や土木工学など資格を持った人がいないとはじめられないものではなく、サービスやシステムに対する好奇心と、SLI/SLOを始めるための機会であると述べています。 また、SREが既に組織に統合されているモデルとして、以下の3種類を定義しています。 1. 中央集権型/パートナー型モデル Googleが最初に導入し普及させたもので、独立した組織として、採用プロセスや、人員、ジョブラダーを持ちます。例えばGoogleでは、GoogleマップのSREチーム、GmailのSREチーム、広告のSREチームが存在します。 2. 分散型/埋め込み型モデル Metaで導入されているモデルで、SREが開発チームに参加します。詳細は、 SREの探求 の第13章に記載されています。 3. ハイブリット型モデル 上記2つのモデルを混ぜて導入したもので、中央集権的な組織で働くSREと、個々の事業部門で個別に雇用されているSREがいます。 弊社が提供するサービスには、ECストアフロントを提供する「BASE」のほか、ID決済機能とショッピングアプリ機能を提供する「PayID」、金融サービスを提供する「BASE BANK」などがあります。(その他のサービスについてはここでは割愛します) これらを上記の3種類のモデルに当てはめると、「BASE」は中央集権型/パートナー型モデルに、「PayID」と「BASE BANK」は分散型/埋め込み型モデルに該当すると考えられます。 このことから、弊社全体としてはハイブリッド型モデルを採用していると言えるでしょう。 SRE組織の進化段階 SREチームの進化に関する概念的な枠組みとして、本書では、SREcon Asia 2018で元LinkedInのBenjamin Purgason氏が行った講演内容を引用しています。この進化段階は5つのステージに分かれていますが、必ずしも順序通りに進む必要はなく、ステージを飛ばして進化することも可能です。 段階1: 消防士 多くのSREチームがこのステージからスタートします。主な役割は障害対応などの「火消し」ですが、重要なのは火災と火災の間に何を行うかです。例えば、この時間を活用して、Dickersonの信頼性の階層構造でいう最初の2つの階層(監視/オブザーバビリティとインシデントレスポンス)の構築や、トイル(繰り返し作業)を撲滅するための自動化(本書では「自動消火装置」と表現)に取り組むことが推奨されています。 段階2: ゲートキーパー(門番) この段階では、SREが「ゲートキーパー」の役割を果たし、システムに関するすべての決定がSREを通過しなければならない状態になります。しかし、ゲートキーパー的な振る舞いは、他の開発者や組織内のメンバーに不快感を与える可能性があります。本書では具体例として、空港の税関職員をイメージした説明がなされています。 段階3: 提唱者 この段階では、SREと他のメンバーの関係がより協力的になります。SREは、設計やアーキテクチャの議論など、ソフトウェアライフサイクルの初期段階から積極的に関与します。これにより、全員が協力して本番環境を構築し、信頼性を高めることを目指します。 段階4: パートナー 段階3の発展形であり、SREとSWEがパートナーとして対等に協力する状態です。具体的には、計画やロードマップの作成を共同で行い、チーム間の連携がより強化されます。 段階5: エンジニア この最終段階では、SREとその他のエンジニアの役割の境界線が曖昧になります。全員がシステムのライフサイクル全体に関与し、信頼性向上を目的とした活動に取り組みます。SREの活動がチーム全体に自然に組み込まれ、信頼性が組織全体の文化として根付いた状態です。 今後の展望 本記事で取り上げた「SREをはじめよう」の内容や輪読会での議論を通じて、SRE文化の醸成や実践への理解が深まりました。今後、弊社では以下のような取り組みが可能ではないかと、輪読会で議論しました。 1.トイル削減を祝う文化の醸成 トリアージ会やOKRを活用したトイル削減活動を継続し、削減したトイルの成果を社内で共有し、モチベーションを高める文化を醸成します。 2. 知識共有の強化 外部イベントやカンファレンスへの参加、登壇を行い、自分なりのSREの定義を語れるようにします。 3. 失敗からの学びを最大化 ポストモーテム会を定期的に開催し、インシデント後の学びを組織全体に共有します おわりに 弊社では、SREの方だけではなく、サイトリライアビリティエンジニアリングに興味を持たれているSWEの方も積極採用しています。興味を持っていただいたら、ぜひ下記からご応募ください! binc.jp
アバター
数値と論理
はじめに こんにちは!BASE株式会社でPay IDチーム プロダクトマネージャーをしているbunです。 Pay IDは、BASEで作られたショップでのお買いものを楽しむためのショッピングサービスとクイックでスムーズな決済機能を提供しています。 去年1年を振り返ると、多くの失敗や思うようにいかないことが重なり、そのたびに内省をする時間を持つことが多かったです。その過程で強く大事だと感じたことは、 プロダクトマネジメントで突き詰めるべきは「誰がなぜ幸せになるのか」を見失わないこと です。 これまで数値と論理を武器にキャリアを積んできましたが、プロダクトづくりにおいてはそれらが最優先事項ではないシーンが多いことを痛感しました。この記事では「数値や論理」をプロダクトづくりの軸とすることの功罪を再確認し、どのように活かすのかを自分なりに整理してみたいと思います。 数値 定量分析とはAかBのどちらが優位かを明確に示し、チーム全体の意思決定に納得・正しさ・早さを持たせることができます。膨大な情報の中から「見るべきポイント」を定義し、そこにフォーカスを当てることで関係者全員が判断基準を共有できることが数値の役割なのではないかと考えています。 しかし、この「明確化」の裏側には、「見ないことを決める」ということでもあります。つまり、明確な基準を設けて特定の指標を追うということは、それ以外の要素に注意を払わない、あるいは軽視することと表裏一体です。結果として、数値ベースの分析に特化しすぎると気づかないうちに視野が狭まってしまうことが往々にしてあります。 事例:キャンペーンクーポン 売上を短期的に押し上げるために「クーポン利用率」という指標を作ったと仮定します。定量的な目標を設定し、クーポンがどれだけダウンロードされ、何%の利用率に達したかをトラッキングすることで、クーポン取得数や利用数を着実に増やすことができ、売上も一時的に上昇し、データ上は「成功」と言える状態が生まれます。一方で「クーポン利用率」という特定の数値指標に照準を合わせることで、定量化しにくいが本質的に重要な要素が視界から消えてしまいます。 ブランドイメージ :クーポンの乱発により、「安売りして当たり前」というイメージが定着し、長期的なブランド価値が下がる可能性がある。 顧客ロイヤリティ :クーポンがなくなった瞬間に離反する顧客が増え、価格以外の価値が見えづらくなってしまう。 あくまで一例ですが数値分析の強みである「わかりやすさ」と「意思決定の明確化」は、同時に「多様な観点の切り捨て」をもたらしていることになります。 数値目標の達成には成功したとしても、“そこには映らない本質”を見落としている可能性があります。定量指標が示す「正しさ」はあくまで条件付きのものであり、広い視野を持たないとプロダクトが壊れてしまう難しさがあります。 見たいものだけみて、数値ベースで施策や行動をすべきと言っている場合はかなり危うい状況なのではないかなと思います。 論理 論理は既に知っている材料や情報を元に、筋道を立てて再配置するための枠組みのことだと考えています。一見すると失敗のリスクを低減してプロセスを合意形成しやすくする一方で、「既存のゲームルールの上を歩むだけ」という側面でもあります。 そのため、顧客の想像を超えない機能は驚きや感動のような心を動かすようなことはできず、大きな結果は生み出せない可能性が高いのではないかと考えています。 誰もが納得する形に落とし込もうとするとどうしても「定量的インパクト」「成功確率」といった言葉で企画やアイデアを語りがちになり、結果的に競合他社との「差別化」も難しくなります。 説得力を高めるための“客観的な説明”を重ねれば重ねるほど、いつの間にかユーザーの顔や感情が薄れていきます。 論理的整合性を高めることは大切ですが、プロダクトを使うのは「人」であり、彼らがどのような喜びや悩みを抱いているかを深く理解することこそが核心ではないかと考えています。 補助線を引くための道具 プロダクト開発でまず問うべきは 「誰がなぜ幸せになるのか」から始まるべきであり、数値や論理はこの問いに答えるうえでの「補助線」にすぎない のではないかなと考えています。施策の検証結果や仮説を得たり帰納的に考えることに限定すべきだと思います。また、 企画段階での施策の正しさは数値と論理ではなく顧客が持つイシューの解像度の深さと実行結果で判断すべき なのではないかなと考えています。 道具の扱い方 数値に左右されすぎない: 数値は短期的成果を測る指標にすぎない。視野を広く持ち、定量化できない部分にも目を向ける。 論理で固めすぎない: 試作や実験のフェーズでは、“熱量”や“直感”も大切にし、顧客の感情や想定外の行動に目を向ける。 哲学・ビジョンを明確に持つ: 「誰が、なぜ幸せになるのか」を常に問い続けることで、数値と論理に翻弄されない軸を持つ。 最後に 数値や論理はもちろん大切ですが、そこに顧客に憑依して“自分たちが本当に欲しい未来”を実装するバイアスが入っていなければありふれた機能しか生まれないのではないかと考えています。たとえよくある機能でもちょっとした気遣いがあるかどうかに差が現れてくると思います。 また、顧客のインサイト(本人が気づいていない隠れた欲望)に仮説を立てて不確実性の高いプロダクト開発をするには試行錯誤しながら素早く検証していくことが欠かせないと痛感しました。 今年は強い熱量や“バイアス”に引っ張られることをポジティブに捉えながら、実際に手を動かし、早くライトに実験し、失敗し、そこで得た学びを積み重ねながらプロダクトマネジメントをやっていきたいと思っています。 binc.jp
アバター
本記事は BASEアドベントカレンダー2024 の24日目の記事です。 はじめに CTOの川口 ( id:dmnlk ) です。 昨日の記事は下記です、それぞれいい記事なんで読んでね。 今、リモートワークについて思うこと 統括マネージャー(EM of EM)の仕事7選 BASE社では現在もエンジニア採用を行っています。 その中でよく質問を頂くのは「BASEに今から入社した場合にやることはあるのか?」というものです。 ここまで読んだBASE開発ブログファンの方はお気づきかもしれませんが、こんな内容の記事を以前書きました。 今BASEに入社してやることあるの?という疑問に答えるよ この記事から3年経った今、現在のBASE社の現状を踏まえた必要とされていることを書いていこうと思います。 サーバーサイドアプリケーションのリアーキテクチャ BASEのメインアプリケーションはCakePHP2系で書かれています。 このアプリケーションのFW移行、リアーキテクチャを数年続けています。 重要機能であるカート部分はリアーキテクチャが完了し現在はCakePHP4系で動いています。 このアプリケーションはCakePHP4系をベースに作られていますが、FWに極端に依存することを避けモジュラモノリスとクリーンアーキテクチャを ベースとしたアーキテクチャを採用しています。 詳細に関しては弊社テックリードが発表したこの資料を参照していただければと思います。 BASE大規模リアーキテクチャリング その後もリアーキテクチャの開発は進んでおり、新機能などは可能な限りこのアプリケーション上に構築するようになっています。 もちろん例外はありますが、その際もなぜ旧リポジトリで開発する必要があるかというのをプロポーザルを書くようになっています。 とはいえBASEの大規模なアプリケーション群はまだまだ移行しなければならないのでこちらの移行開発をスループット高く移行開発する必要があります。 このあたりの基盤開発やレガシーアプリケーションのマイグレーションなどを行いたい方のご応募をお待ちしています。 不正検知 BASE社はPAY株式会社を子会社に持ち、PAY.JPというオンライン決済サービスを有しています。 よって、EC取引から決済処理に至るまで、横断的かつ包括的な不正検知の仕組みを構築できるユニークな立場にあります。 これまでに不正検知システムを構築し、一定の成果を上げてきました。しかし、急速に進化するサイバー犯罪や不正な決済に対応し続けるため、さらなる強化が必要です。この取り組みは、BASEやPAY.JPを利用する顧客や加盟店の安全性を確保し、信頼されるサービスを提供するために欠かせないものです。 決済のトランザクション処理やECの購買データなどを利用し、横断的により効果的な不正検知システムを構築していける方を募集しています。 レコメンド これは Pay ID チームが主体となりますが、Pay IDでは多くのショップの商品を有しており多種多様な顧客ニーズに応えています。 しかし、商品の多様性が豊富である一方、膨大な商品データから顧客が適切な商品を見つけるのは容易ではありません。この課題を解決するために、レコメンドシステムは不可欠な役割を果たします。 膨大な商品データをリアルタイムに処理していくには計算リソースの管理と効率的なアルゴリズムが求められます。 このようなレコメンドシステムを構築していくにあたりデータサイエンスや機械学習のスキルだけでなく効率的でハイスループットなインフラストラクチャを構築していかなければいけません。 レコメンドシステムのさらなる進化を共に追求し、新たな購買体験を創り出しした方をお待ちしています。 グループ間連携と技術ガバナンス 先日、BASEは越境EC事業を展開するwant.jpの株式を取得し子会社化しました。 子会社化したからといってすぐさまBASE社がすべてを管理していくということにはなりませんが、これから密接な連携を行う予定です。 その上でグループ間でのアプリケーション連携や開発組織を構築していく必要があり、技術水準やセキュリティ水準も合わせていくことになります。 このような経験を行ったことは自分自身がないため、知見を持っている方をお待ちしております。 グローバルプロダクト 越境EC事業を行っている会社を子会社化していることからも分かる通りBASE社はグローバルなプロダクトへの道筋を模索しはじめています。 BASEそのものをグローバルプロダクトにしていくかは現状不透明ですが、世界を見据えたプロダクト開発が必要になっていくことはわかっているため 開発組織の大幅な変更や、グローバルに展開するプロダクトに必要な技術開発をご経験された方をお待ちしております。 SLI/SLO BASEでは決済取引の信頼性、ページの高速なレスポンス、そして常時アクセス可能なサービスの提供が、ビジネス成功の鍵を握っています。特に、売上に直結する「サービスの品質」は、私たちにとって最優先課題です。 そこで私たちは、システムの信頼性を数値で明確に示し、適切な目標を定めるために、SLI(サービスレベル指標)/SLO(サービスレベル目標) の策定に取り組み始めました。この取り組みを通じて、例えば「カートページのレスポンスタイムはXms以内」や「決済処理の成功率はX%以上」(あくまで例です)といった具体的な目標を設定し、サービス品質を改善していきます。 SLI/SLOの策定は、単なる技術的な改善ではありません。それは、「ユーザーにどんな体験を届けたいか」をチーム全体で考え抜く作業でもあります。ECプラットフォームという特性上、ユーザーは少しの遅延やエラーでも離脱する可能性があります。だからこそ、私たちはシステム全体の動きをデータに基づいて把握し、予防的に問題を解決することで、ユーザー体験を最適化したいと考えています。 この活動には主にNewRelicを利用しています。 この活動を行うのは特別なロールというよりは開発エンジニアそれぞれが取り組んでいくべきことです。 今後、SLI/SLOを基盤に、より信頼性の高いシステムを構築し、チーム全員が共通のゴールを目指せる環境を整えていきます。この挑戦に参加し、私たちと一緒に「より良いECプラットフォーム」を作り上げてくれる方を募集しています。 セキュリティ こちらも前回の記事で書いていましたが、セキュリティの重要性は年々増しています。 他社事例にはなってしまいますが、セキュリティインシデントによる事業停止のリスクは非常に大きくなっていますし攻撃は高度化しています。 BASEアプリケーションだけでなく社内システムや従業員教育なども必要になっており、CISO担当と共に行動していただくことになると思っています。 セキュリティと開発体験などはトレードオフとされがちですが、セキュリティのために開発のスループットを落とさずセキュアにハイスピードで開発できるようにしていくことを目指しています。 AWSインフラのコスト最適化およびモダン化 BASEを支えるAWSインフラのコスト最適化およびモダン化に積極的に取り組んでいます。これらの施策は、効率的な運用とスケーラビリティの向上を図りながら、より優れたユーザー体験を提供するために欠かせないものです。 ECプラットフォームにおいて、トラフィックの増加や利用者ニーズの多様化に伴い、インフラコストが上昇することは避けられません。 加えて昨今の円安事情によりコスト最適化は継続して行うイシューという意識となっています。 しかし、単にコストを削減するだけではなく、システムの信頼性やスピード、柔軟性を維持しながら最適化することが求められます。また、新しい技術を導入し、技術的負債を解消することで、将来の拡張性や運用効率を確保しています。 コスト最適化においてはインスタンスなどのリソース利用の動的な変更やモニタリングの強化、画像配信のネットワーク最適化などを取り組んでいます。 モダン化においてはコンテナ化やIaC、効率的でないインフラ構築手順の簡素化などを取り組んでいます。 SREチームが主に取り組んでいますが、開発者それぞれが取り組んでいくべき課題と捉えていますのでアプリケーションインフラを積極的に触れていきたい方をお待ちしています。 おわりに これらだけでなくまだまだ多くの課題や未来への開発をBASE社は抱えています。 技術はあくまで手段ですが、私達の開発組織を構成するエンジニアとして積極的に技術研鑽をして事業とプロダクトにコミットしていくことを求めています。 やることない、なんてことは全くないのでカジュアル面談からでもよいのでBASEに興味を持っていただければと思います。
アバター
本記事は BASEアドベントカレンダー2024 の24日目の記事です。 はじめに こんにちは!BASE事業エンジニアチームにて責任者(エンジニアリングマネージャー)をしている 植田 です。いよいよアドベントカレンダーも今日を含めてラスト2日となりました。今日や明日クリスマスを楽しむ方も多いのではないでしょうか。 さて、私は今回、”統括マネージャー(EM of EM)”とはどういう仕事か、日々どんなことを考えて仕事をしているかをお届けしたくアドベントカレンダーを執筆しました。 想定読者は以下の方々になります。 現在エンジニアリングマネージャー(以下EM)をしていて今後EM of EMを目指していきたい方 統括マネージャーとはどんな仕事なのか興味のある方 私の組織を簡単にご紹介 まず私の組織と私の立場をご紹介します。 はじめに組織構成ですが、Product Dev DivisionがBASE事業の開発チームになっておりDivisionの配下に複数の開発チームが存在していて、開発チームにはEMがつきマネジメントしています。 続いて、開発組織のミッションは大きく分けて3つあります。 BASE事業におけるフィーチャー(機能)をデリバリーしていくこと 既存機能を運用・保守していくこと 技術課題を解決していくこと 私のミッションはこの組織全体のパフォーマンスを最大化し、安心安全なプラットフォームを構築していくことになります。今日は私の立場を”統括マネージャー”と表現し、普段の仕事について紹介していきたいと思います。 統括マネージャーの仕事7選 全てではありませんが自分が重要であると考えている仕事を7つ書き出してみました。 組織の方向性を打ち出し、組織のベクトルを揃える 未来を見通し、先手を打つ EMを通して組織を動かす 開発組織として何に投資するかの意思決定 組織作り 隣接組織とのハブ役 現場メンバーとのコミュニケーション なお1人の人間はそこまで万能ではないので、これらを1人きりでやっているということではなく、頼れるEM陣と日々協力しながら実行しています。それではそれぞれの仕事を細かく紹介していきます。 1. 組織の方向性を打ち出し、組織のベクトルを揃える 私が統括マネージャーの任用を打診されたときに始めに考えたアクションはこちらでした。私の組織は数十人のエンジニアが在籍しているのですが、何もせずとも開発は自然と進んでいく、しかし果たしてその推進力は最大化できているだろうか、と。どんなに優秀なエンジニアが在籍していてもバラバラの方向を向いていてはその力は最大限発揮することはできない、きちんとビジョンや方向性を打ち出すことで、パフォーマンスが最大化できるのではないかと考えたことがきっかけでした。方向性は打ち出して終わりではなく、それに対して理解を深めたり浸透させていくことが大事です。これは時間がかかる話しなので現在進行系ですが、ビジョンや方向性を打ち出すことで、統括マネージャーとしての考えや行動に1本筋が通り良かったと考えています。 方向性を打ち出したことの細かい話は以下の記事でも触れているので、そちらも合わせて読んでいただけたら幸いです。 https://basebook.binc.jp/entry/2024/10/04/132904 2. 未来を見通し、先手を打つ 組織の中では立場や役割によって、どの程度先を見据えてプロダクトや組織を考えるかが変わってきます。現場のメンバーであれば現在〜3ヶ月先、チームを任せられているEMであれば半年〜1年くらい、統括マネージャーであれば1〜3年くらい先を見通せるのが理想的かもしれません。統括マネージャーの立場であるのに現場とまったく同じ目線で仕事をしていては、少し先の未来に想定していないことが起きた時、組織ごと沈没してしまいますし、すべてが後手後手に回ってしまいます。未来を見通し舵取りしていくからこそ組織はよどみなく成長していくものだと考えています。よって可能な限り未来を見通し計画を立てていくのが重要なのですが、私も3年先のことを解像度高く考えられているかというとこれは容易ではなく修行が必要だと考えています。 3. EMを通して組織を動かす 統括マネージャーになることの1番大きな変化は、直接的にメンバーをマネジメントしなくなる、ということかもしれません。メンバーと直接接点があれば、PJに対するアドバイスもリアルタイムでできるし、メンバーのキャリアや成長に対するアドバイスもやろうと思えば毎週できます。メンバーと直接定期的に会話するのでメンバーや現場のことに対する解像度も高く維持できます。ですが純粋な統括マネージャーはメンバーとの接点は減ってしまうのでその利点を失うことになります。そうなった時に重要なのが自分の配下のEMと会話し意思疎通し、または自分の考えを伝え、それを広げていくことです。また立場的に役員の方々と直接会議したり会話することも増え、それだけ重要な意思決定や情報に触れているわけでもあります。そういった一次情報に触れているわけなので可能な限りEMにも連携し情報格差をなくし同じ視野で組織運営できる状態を整える、それも統括マネージャーの重要な仕事だと考えています。 4. 開発組織として何に投資するかの意思決定 前提として、事業成長のために開発を行っているわけなので、開発組織のみで何をしていくかを考えているのではなく、基本は事業における優先度に則り必要な開発をしています。という基本的な考えがある中で、目先の事業成長だけを考えていると、少し先の未来に起こり得るシステムのパフォーマンス問題やセキュリティリスクといったものは見過ごされがちになってしまいます。BASEではQごとに計画や目標を立てるサイクルになっていますが、計画や目標を考えることはつまり何に投資するかの意思決定であると考えています。事業成長のためにどんな開発をしていくのか、プラスアルファで開発組織としてやるべきことはなにか?を常に考えて行動しています。 5. 組織作り 組織作りは、組織構造を考えること、メンバーを育成すること、採用を通して新たな仲間を見つけてくること、組織の文化形成などがあげられます。統括マネージャーという立場であれば、単一チームを超えたより広い視点で組織を考えていくことが求められます。事業をさらに加速していくためにはどんなチームが必要か、どんな人材がどれだけ必要か、誰をどこに配置すべきか、開発をさらに加速させるために必要な文化とは何かを計画し、育成、採用、文化形成それぞれの手段をミックスさせながら組織作りをしていきます。 6. 隣接組織とのハブ役 BASE事業においては、BizDev Division、Marketing Division、Owners Success Divisionなどが組織を構成し事業を支えています。そのような隣接組織と互いの期待値を調整をしたり、具体的な業務を依頼したり依頼されたりといったコミュニケーションが日々発生します。ある程度現場チームに紐づく業務は自分が介入せずに済むことも多いですが、いわゆるチームの間に落ちるボールや、突発的な案件などは直接相談が舞い込むことも多く、なるべくなめらかに互いの組織の業務が進むようにハブとなるのも大事な仕事です。組織の顔として動くことにもなるため一定の緊張感を持って臨んでいます。 7. 現場メンバーとのコミュニケーション さきほどEMを通して組織を動かすということを紹介しましたが、とはいえメンバーと直接会話する機会を作ることも大事です。現在は3ヶ月に1度の頻度でメンバーとの1on1の時間を設けています。いわゆるスキップレベルミーティングですね。メンバーから声がかかるのを待つのではなく能動的に自分からコミュニケーションの場を作っています。メンバーと直接会話し現在はどんな様子なのか、組織に対して課題に思っていることはないかなどをヒアリングしています。会話をすることでメンバーに対する解像度が高くなりメンバーに対する持論を持つこともできます。自分のポリシーとしてメンバーと話した内容はEMの方にも共有するようにしています。EMの立場から見て自身の見えないところで、メンバーと上長が会話しているというのはソワソワするものです。よってメンバーに許可を取った上でメモは共有するようにしています。またメンバーとEMの信頼関係を超えて自分が不必要にメンバーと蜜月にならないようにもしています。それはチームとメンバーをマネジメントしているEMという立場を尊重しているからです。 おわりに 本日は統括マネージャー(EM of EM)の仕事を7つ紹介しました。1つでも参考になる話があれば幸いです。BASEではWebアプリケーションエンジニア、エンジニアリングマネージャー、テックリードそれぞれ積極的に採用中です。ご興味ある方はお気軽にお声がけください。 さて、明日はアドベントカレンダー最終日です、毎年恒例弊社 CTO の記事ですのでお楽しみに。 binc.jp
アバター
本記事は BASE アドベントカレンダー 2024 の 24 日目の記事です。 こんにちは、エンジニアリングマネージャーの松原( @simezi9 )です。 新型コロナウイルスの流行に端を発する世の中の変動からもうじき5年が経過しようとしています。 当時の感染対策の流れで多くの企業がリモートワーク制度の導入を進めました。この記事を読んでいる方の中にもそのタイミングではじめてリモートワークに取り組んだ方も多いのではないでしょうか。 私もその当時に、BASE株式会社のリモートワークへの取り組みをエントリとして公開したことがありました。 参考: エンジニアのリモートワーク in BASE このエントリを書いてから4年。その間、マネージャーという立場からリモートワークの制度を運用してきた経験を踏まえて、私がいまリモートワークというシステムに対して思っていることを率直に書いてみたいと思います。 この文章が、リモートワークの導入・廃止で悩む管理者や、それらの決定がどういう経緯のもとで進んでいるのか納得できないメンバーの方々の理解の助けになればいいなと思っています。 (エクスキューズ)BASEではリモートワークの運用はチームに任されている部分が多く取り組み方も千差万別なので、前述のエントリとは違ってこの記事は会社全体の取り組みとは一切関係がなく、一人の中間管理職としての私見を述べたものであることは事前にご認識いただければと思います。 世の中のリモートワークに対する反動 まず、この4年ではっきりしてきた流れはリモートワーク制度への反動であると思います。 コロナウイルスの世界的な流行をきっかけに普及したということは、その制度は言い換えれば外的な動機によって駆動されていたものであり、内的な動機に支えられたものではなかったと言えるかと思います。 そしてその制度にチャレンジした結果として、「組織の結束力が弱まる」「イノベーションが生まれなくなる」といった理由で制度の縮小・撤廃をしていく企業がどんどん現れているように思います。 これは日本企業のみならずアメリカのビッグテックであっても同様、というよりむしろ顕著であって、Google,Apple,OpenAIといった世界を代表する企業であってもリモートワークに否定的なスタンスを取り、出社にかじを切り直そうとしている事例はいくらでもでてきます。 SNSなどを眺めていても、出社のルールを設定したい会社とそれに抗う社員という構図はよく見かける光景になったと思います。 あらためて、その功罪について自分の考えを述べてみたいと思います。ここでは一般論として言われていることは前提として省いて、あくまで私自身が強く感じるメリット・デメリットのことを書いていきたいと思っています。 リモートワークのメリット メリットについては正直、世間一般で言われていることがすべてという感じで、改めて書くようなことも少ないのですが、とりわけ大きいなと思うことだけにとどめて書きます。 ワークライフバランスの取りやすさ 育児の最中、あるいは持病を抱えている方、家族の介護を抱えている方にとっては通勤による拘束時間が短くなって勤務中にもちょっとした割り込みタスクを捌ける、生活と両立ができるというのは大きなメリットとして存在しています。仕事の存在によって日々のスケジュールが圧迫されて大変だと思う瞬間は減ったように思います。 通勤時間の節約 特に不動産価格の高騰が続く首都圏にあっては顕著ですが、片道1時間の郊外からの通勤時間が不要になるというのは大きいメリットです。会社としても交通費用の手当が不要になり、社員側も毎日長い通勤時間の拘束が減り、満員電車で疲弊してしまうという事態も避けられます。 リモートワークのデメリット こちらは組織を運営する立場の人間として、思うことが多かったので分量としては大きくなります。デメリットというべきではなく、賛否がある考えも多く含まれています。 組織力の低下 「社員の総業務委託化」 表現としては少し過激ですがリモートワークが標準の組織にあっては、オフィスで働いていた頃ほどの人間関係を結ぶのは相当に厳しいものであると感じています。 普段のコミュニケーションの輪はどうしてもチームの外には広がっていきませんし、淡白な働き方にならざるを得ない部分はあるかと思います。 これは組織のサイロ化として、リモートワークの欠点として挙げられていることが多いように思います。 実際に、会社が何を考えているのかわからなくなった、他のチームが何をしているのかよくわからない、という話をしている光景を目にする機会は体感として増えているような感触は受けます。 また、スキルのポータビリティが高く、転職が容易な技術職にあっては、傭兵のように働き、飽きたら次の現場にさっと移ってしまうという動きも増えたように感じています。 リモートワークが標準になることで転職のハードルも大きく下がりました。場所も知らないあちこちのオフィスに何度も訪問して面接をする、という大変な過程が減り、とりあえずZoomやMeetで最初の面接をするという流れに変わったことは大きいと思います。 少数の社員で役職の垣根を超えて密なコミュニケーションで理不尽や不条理を乗り切らないといけないフェーズの会社ではこれは非常に苦しい状態であるかと思います。 あるいは、リモートで身体感覚を伴わず入社してきた方が、広い人間関係を構築することなくリモートでふらっと次の職場に移っていく光景もよく見かけました。 そしてそれを阻止するべくオンボーディングのプロセスを丁寧に行う、ということもよく行われていたように思います。ただオンボーディングだけで組織への愛着を醸成するのは難しいことでもありそうです。(第一歩としては重要だと思います) ウェットな人間関係を仕事に持ち込むことに対して否定的な考えもありますし、それはそれで尊重されることだと思います。なので、制度を考える側は自分の組織がどういう形であってほしいのか、というのを考えて選択する必要があります。 わたし自身はオフィスで働いていた頃に比べると、リモートワークは「刺激に乏しく退屈である」という印象をもっているのは偽らざるところです。 これについては特にマネージャーとメンバーの間で感覚の分断が大きい領域であると感じていてます。責務を与えてくれればこなします、それでなにか不足はありますか、というメンバーからの指摘と、明確な形にはしづらいが組織体の強化において出社は重要であると考えるマネージャーの間の分断は少なくとも自分が社内外で話を聞いたところでは一定起きているような気がします オンラインミーティングの難しさ ここについては特に個人の感想という部分が大きいのですが、対面で行われるミーティングに比べて、オンラインミーティングはとても難しいと感じています。 それはボディランゲージの情報量がガクッと落ちてしまったり、会話の間がつかみにくくやり取りが盛り上がらないことであったり、原因は様々考えられます。以前なにかの記事では対面と比べてオンラインだと伝わる情報量が7−8割落ちるなんて話も見た覚えがあります。 私自身もオンラインミーティングは画面に集中するのが難しく、つい他のウインドウを見に行ってしまったり、会話に参加し続けるのが難しいと感じる瞬間がよくあります。 また、オンラインミーティングは会議室という物理的制約を受けないため、無駄に何人も参加者を増やしてしまっても成立してしまう、という特徴があります。結果として、15人参加しているけれど10人は画面もマイクもオフで残りの5人が会話してるだけ、という超絶に不毛な時間が生まれたりすることがあります。会議室で行うミーティングではこういうことはなかなか起こりません。 オンラインミーティングの主催者は人数を絞り、議題を明確にし、参加者の集中力を切らさないようにするために、対面のミーティングよりもはるかに気を配る必要があります。 一度始めると廃止のハードルが高い リモートワークの話に戻りましょう。 一般論として、一度獲得した権利を奪われる、ということに対して人は強い抵抗を示します。 そしてその理由というものは、通勤が嫌だ、というようなちょっとした目の前に見える問題に対する拒否反応であったり、地方に家を買ってしまったからそんな簡単に出社をベースにできないといった大きな問題まで様々です。 リモートワークの制度を縮小する可能性が少しでもあるならば、この制度はあくまで現時点のものであり永続的に保証されているものではない、というのを事前に確認しておくべきです。場合によっては労使契約でちゃんと確認していく必要もあるでしょう。 でないと制度を変えたときに一挙に離職が発生するリスクにもなりますし、会社にとっても労働者にとっても不幸な結果になってしまいやすいです。 特に、フルリモートで働けます、というのをウリ文句にして求人を出している会社は世の中にも少なからずありますが、その制度の将来性というのはなるべく開示するべきだと思います。またその一方で労働者の側も、リモートワークの制度が長く保証されているケースは少ないということを認識しておくべきことであると思います。 少なくともある程度の広さのオフィスを構えている会社はいつオフィス回帰という判断を下してもおかしくはない、というのがわたしの印象です。 リモートワークという制度を導入するのはそれほど難しくない(情報セキュリティやワークフローの構築といった実務の問題は当然あります)のに比べると、その規模を縮小したり廃止するというのは会社をひっくり返すような騒ぎになりかねません。 制度を運用する側はその点を非常に重く考えて制度を設計するべきであると考えています。 リモートワークの性質 メリット、デメリットではなくリモートワークってこういうことがありがちだよね、というのを列挙してみます。 アウトプットに評価の比重が大きく偏る リモートワークにおいて、普段の業務態度、ふるまいなどは視界に入りにくくなります。 そのため、「その人が何をしたか」という形に残るアウトプットにのみ評価の根拠が置かれる極端な成果主義になりやすいと感じます。 腕に自身がある人にとってはそれで十分だと思うでしょうし、対面でのソフトスキルに自分の価値があると思う人は苦戦を強いられることもあるかもしれません。 特にオンラインで入社してきた人は否が応でも自分の価値を具体的な作業で主張する必要があり、職場への適応に苦労することも多いのではないかと思います。 ハイブリッドワークは本当にちょうどいいのか オフィスへの出社とリモートワークを使い分けるハイブリッドワークという単語も世の中ではよく使われるようになったと思います。 単に「出社してもいいよ」から「最低でもこの日は出社してください」というパターンまで濃淡は様々見受けられます。 これはリモートワークとオフィスワークのいいとこ取りをしようという動きのようでいて、実際のところはリモートワークの欠点を補うために少しでもオフィスワークを取り入れよう、というコンテキストから増えてきた動きである、という感覚のほうが近いような気はしています。 しかしながら、このハイブリッドワークの取り組みはオフィスワークとリモートワークの悪いところどりにもなりかねない一番難しい取り組みなのではないかと感じています。 出社日を決めないパターンでは結局オフィスに来ない人が徐々に増えていってあまり機能しない状態に陥りやすいですし、出社日を設定するパターンであっても出社日の決め方や、オフィスならではのコミュニケーションがちゃんと発生するような仕掛け、そういった配慮がないと、「単にオフィスに呼び出されて嫌々出社するだけの日」に陥りやすい気はしています。 現実のオフィスとそこで行うチームワークをいかに魅力的にするか、管理者の力量が非常に求められるところであると感じています。そこにコストをかけないのであればおそらくハイブリッドワークはうまくいきません。 形骸化しやすい「出社日」 前項での話に近いのですが、出社日というものに効力をもたせるには一定の規律が必要です。 せっかく出社日をつくったところで「今日は頭痛いので家でやります」(そんな移動できないほど頭痛いなら出社しないとかではなく休暇を取って休んでほしい)といったことがカジュアルに行われるようになるとその意味は薄れていきます。 「やむにやまれぬ事情」の基準は人によって千差万別でありどこまで配慮するべきか大変に難しい問題となります。 そして誰かがオフィスにいない場合、会議もオンラインで実施する必要があり、オフィス組と自宅組の分断が生まれたりして、「なんだかいろいろやりづらい」という状況を招きます。これは特に出社体験を良くするための仕組みを色々用意していればいるほど起こりやすい状況であると思います。その状況では1人でもリモートワークの人がいるとチーム全体の出社体験が悪化す る、という認識を全員が持っておく必要があるかな、と思います。 本当に出社日を設定するなら安易に例外を作らない、という強い気持ちが管理者の側に要求されるように思います。とりあえず出社日を作ればいろいろうまくいくはず、というのはあまり現実的ではないと感じています。 フリーアドレスの功罪 これはリモートワークの話からは少しそれるのですが、リモートワークを導入してオフィスの稼働率が減っていく中、採用によって人員が増えると固定席を割り当てる意義が低下していきます。 オフィスにこない人員のデスクのためにオフィスを増床したりレイアウト変更するコストを払う必要はない、ということでオフィス側でフリーアドレスを導入する企業もちらほらと見かけます。 表面的には非常に合理的な手法なのですが、これはこれで用心する必要があると思っています。というのも、フリーアドレスにすることで自分の愛着の持てるデスクがなくなり、毎回行ってみないとデスク環境がわからない、というところでオフィスをますます敬遠する結果になりかねないからです。 またフリーアドレスということでチームのメンバーで会話する機会が机が離れて物理的に分断されることで奪われてしまう可能性もあります。 フリーアドレスも慎重に行わないと、「家がメインでオフィスはたまに行く場所」という認識を定着させかねないものであるということは留意しておく必要があるように思います。 生産性は向上するのか 昨今ではとりわけ「生産性」というワードが注目を集めているように感じます。 リモートワークにまつわる議論でも、「リモートワークではサボるから生産性がさがる」「家で働くほうが落ち着いて取り組めるので生産性が高い」、といった素朴なところからはじまり様々な声を見かけます。 この議論についてはおそらく結論が出ることはないだろうと見ています。 そもそもの生産性という言葉が何を指しているのかの定義が非常に難しいですし、職場や組織の条件次第であまりに変数が多く価値のある統計データを導き出すことも難しいように感じているからです。 例えば、オフィスのレイアウトをオープンにするほうがいいか、ちゃんと仕切りを作ってクローズドな環境を作ったほうがいいか、というような話題も未だに決着がでているようには見えません。 それを思えばそれ以上に変数の多いリモートワークの生産性について一般的な結論が出ることを期待するべきではないでしょう。 結果として、「生産性のためにリモートワークを廃止する・維持する」という議論は双方が納得することなく不毛に終わることがほとんどであるように思います。 SNSでも「リモートワークがうまくいくと思っている人はレベルが低い」「リモートワークで生産性が落ちる職場のレベルが低い」というような根拠のないレッテル貼りや煽り合いに終止してしまっている光景をよく見ます。 組織の制度を決定する権限を持っている人は、この生産性という概念を議論に持ち込まないほうが意思決定の根拠を揺らがずに決めることができるのではないだろうかと思っています。 最後に:管理者として揺れ動く中で ここまでデメリットやネガティブな話の比重がかなり多くなってしまいました。これは、私自身が心の何処かでリモートワークはあまり良くないものだ、と考えている結果なのかもしれません。 リモートワークはメリット・デメリットで天秤にかけるものではなく事業の利益には相反する福利厚生なのであると割り切って考えるべきなのかもしれません。その場合は事業へのダメージをなるべく減らしながらリモートワークを行う、という考え方になるのだろうと思います。 結局のところ、リモートワークを成立させるのは諸々の前提が必要であり、組織の上から下までその難しさを認識して取り組んでいく必要があるものだと思っています。 その最たる例がGitLab社であると思います。同社はリモートワークで働くために必要な非同期コミュニケーションを徹底的に整え、 ガイドラインを公開しています が、逆に言えばそれだけのコストをかける覚悟が必要であるという証左でもあると思います。 私自身は、リモートワークの難しさに立ち向かう手間と予算を払う覚悟がなければ、オフィスで仕事をしたほうが最終的に会社の利益にはつながるのであろうと思っています。 一方で管理職といえど従業員の立場であることは変わらないのであって、リモートワークから得られる利益を捨てる決断をしがたいのも事実であります。 この部分の決断は中間管理職や現場の判断ではなく、リモートワーク継続にせよ廃止にせよ、経営者やそれに準ずる立場の人間がバシッと決めてルールにしてしまうことが必要なのだろうと思います。各位に裁量を渡した状態では組織が全体として引き締まることは難しいように感じています。 それで組織を去る人もいれば、そういう組織を求めている方もいる、というのは実感としてあるので組織を作る基盤としてしっかり意思を示していくことが大事であると感じています。 リモートワークにまつわる議論は広範に行われていて、私自身も綺麗に文章として整理し切ることができず、このエントリを書くのにも非常に苦労しました。その割に綺麗にまとめきれず大変悔しいところではありますが、皆様の労働がより楽しく充実したものになれば、と思っています。 明日はいよいよアドベントカレンダー最終日、弊社CTOの @dmnlk による記事です。お楽しみに!
アバター
はじめに BASEのProductDev でエンジニア をしています endu です。 本記事は BASE アドベントカレンダー 2024 の 23 日目の記事です! 昨日は @zan_sakurai さんで 「 今年の記事をふりかえってみた 」でした! 記事の中で「イベントレポート・スポンサー・登壇に関する記事が多かった」とありましたが、この記事もイベントレポート記事になります! 2024年を締めくくるイベントという事で2024/12/22(日)に開催された 「PHP Conference Japan 2024」の参加レポート記事をご紹介します! BASEのスポンサーブースの紹介につて 前回のテックブログ でも書いたようにBASEはゴールドスポンサーで協賛しました! 今回も参加者の方に楽しんでもらえる企画として「PHPerあるある」と言うアンケート形式の付箋ボードを用意しました! 付箋ボードには事前に3つのお題を用意してあります。 PHPerあるある PHP系カンファレンスあるある 言語、OS、FWあるある 参加者には好きなお題を選んで頂き、付箋で解答を書いてもらったり、同意する解答が既にあればシールを貼ってもらう形で企画に参加してもらいました。最初企画を用意したときはボードが埋まるか心配だったのですが、当日は想定していたよりも沢山の来場者に参加していただき、企画を考えたBASEスタッフ一同、嬉しく思います! また、企画に参加していただいた来場者にはBASE制のオリジナルノベルティとして、簡単な小物が入る特性の巾着袋と、「BASE」をご利用いただいている COZY COFFEE さんのコーヒーパックを配布しました! 巾着袋に関しては来場者から「かわいい」、「普段から使えそう!」というコメントを頂き、良かったです! 当日見たセッションについて PHP RMは何をする?コア開発者と兼任するメリット fortee.jp PHP8.4でRelease Managerになった Saki Takamach iさんによるコア開発者だからこそ語れる登壇内容で面白かったです! 自分はこの発表を聞く前まではPHPのコア開発者用のSlackがある事や、ベテラン1人と、ルーキ2人の3人体制でリリース体制を行っている事を全く知らなく、思ってた以上に色んな国の方がコミュニケーションを取って開発をされているだなと学びました。 個人的に英語でのコミュニケーションでの謎翻訳の紹介がすごくて笑ってしまったのですが、気になる人は是非、Youtubeでも公開されているのでご覧になってください! www.youtube.com そーだいさんに聞く!コミュニティとともに在るエンジニアの良いキャリアの歩み方 by 大倉 潤也 fortee.jp 個人的にこの発表で印象に残っているワードとして「キャリアアンカーとキャリアドリフト」という言葉があります。キャリアは必ずしも計画通りに進むわけではなく、偶然の出会いや出来事が大きな影響を与えるこという話の中で、そーだいさんは「自分の軸(キャリア・アンカー)」を持つ重要性も強調されてました。その上でカンファレンスで登壇したり、コミュニティに入って社外の方と関係性を持つ事が新しい環境を作り、学びが得られるんだなと話を聞いていて思いました。 speakerdeck.com おわりに 昨年に引き続き今年もスポンサーの協賛を通して PHP コミュニティの盛り上がりに貢献でき、弊社としても大変有意義な時間となりました! 登壇された方や、スタッフの方々も業務でお忙しいにも関わらず、多くの時間をカンファレンス準備へ注いでいただいたかと思います。この場を借りて御礼申し上げます。 また来年の開催を楽しみにしています! ありがとうございました! BASE は現在エンジニア積極採用中なので興味があれば採用情報もぜひご覧ください! binc.jp
アバター
はじめに こんにちは。BASEのDataStrategyチームで機械学習を触っている竹内です。 機械学習といえばLLMやDiffusionモデルなど生成モデルの発展が目覚ましい昨今ですが、その一方で構造化データに対して特徴量エンジニアリングを行い、CVを切って、LightGBMなどの便利な決定木ベースのフレームワークに投げて、できたモデルの出力を吟味し、時には致命的なリークに気付き頭を抱えるといった王道のアプローチは相変わらず現役で、実務に関していえば当分お世話になる機会が減ることはないかなという気がしています。 今回はそういったクラス分類モデルにおける性能の評価指標の1つである、ROC曲線やAUC、PR曲線といった概念について振り返りつつ、実務上しばしば見られる不均衡データに適用する際の注意点などについて、軽いシミュレーションも交えつつ掘り下げてみようと思います。 ROC曲線 2クラス分類器の性能を評価する際によく使用されるツールとしてROC Operating Characteristic)曲線が挙げられます。 ROC曲線は縦軸に再現率(Recall)、横軸に偽陽性率(False Positive Rate)をとり、それぞれの検出閾値に対する再現率、偽陽性率をプロットすることで得られる曲線です。ROC曲線の下側の領域の面積をAUC(Area Under the Curve)と呼び、その面積の大きさによって分類器の性能の高さ、つまりその分類器がどの程度うまく正例と負例を分離できているかを評価することができます。 同じデータセットにおける異なる2つのモデルの性能を比較する際や、再現率と偽陽性率のトレードオフを考慮した適切な閾値を決定する際にROC曲線のプロットは有効な選択肢の1つとなります。 model_1よりmodel_2の方がAUCが高いため、model_2の方が性能が高いと判断できる。 不均衡データにおいてROC曲線を扱う際の注意点 実務において2クラス分類器を適用する例はいろいろありますが、例えば「ある工場の部品生産ラインにおいて、ごく稀に発生する不良品を検知する」といった不良品検知や異常検知、不正検知などの文脈においては、正例に対して負例のサイズが極端に大きい、いわゆる不均衡データを扱うことがしばしばあります。 そうした極端に不均衡なデータにおいては、ROC曲線におけるAUCの指標がうまく機能しないことがあります。 具体的にはROC曲線は適合率(Precision)の指標を含んでいないため、「正しく検出できた正例に対して、巻き込んで検出してしまった負例がどれだけ多いか」という点が考慮されず、結果として非常に多くの偽陽性が発生してしまっていてもAUCは高い値を示してしまうことがあります。 先ほどの工場の不良品検知の例で言えば「AUCの値はほぼ1であるにも関わらず、稼働させてみたら不良品の見逃しは少ないものの、大量の偽陽性が発生してしまうことで、後続の目視チェックの工程をパンクさせてしまう。」といった問題を生じさせてしまう可能性があります。 また、しばしばそうした不均衡データにおいてはある程度の性能であればどのモデルのAUCもほぼ1に近い値を取るようなROC曲線がプロットされてしまい、異なるモデルを比較することが難しいこともあります。 PR曲線 ROC曲線と同様な概念としてしばしば用いられることがあるPR(Precision-Recall)曲線は、縦軸に再現率(Recall)、横軸に適合率(Precision)をとったものです。こちらはROC曲線とは異なり、横軸に適合率を採用しているため「正しく検出できた正例に対して、巻き込んで検出してしまった負例がどれだけ多いか」を反映することができます。 そのため、ROC曲線における高いAUCが観測できていても、データに不均衡性がみられる場合はPR曲線もプロットしてみることでモデルの性能に関する示唆を得られる可能性があります。また、ROC曲線におけるAUCについては差がほとんど見られない2つのモデルの性能を比較する場合においても、PR曲線における改善がみられるケースもあります。 データに不均衡性がみられる場合はROC曲線だけでなくPR曲線のプロットも見ておくと良いかもしれません。 実験 簡単なシミュレーションを行うことで、不均衡データにおけるROC曲線とPR曲線の性質について軽く検証してみます。 まず、正例は平均3、負例は平均1で分散は共に1の正規分布にしたがう特徴量Xもつことを既知とした上で、Xが閾値以上のものを正例、閾値以下のものを負例として分類するモデルを考えます。 その上で、正例のデータは1000件に固定し、負例の方は正例の件数の1倍、10倍、100倍、1000倍の4つのパターンで生成し、このモデルの性能を評価することを考えます。 上図は生成されたデータのヒストグラムであり、負例が多くなると潰れて見えなくなっていますが、正例のデータは4パターンで全て同じものを使用しています。 緑色の点線は閾値を示しており、モデルはこれより右側のものを正例、左側のものを負例として識別することになります。 図では閾値1.5の例を示していますが、ROC曲線やPR曲線をプロットする際はこの緑色の点線を左端から右端へ移動させた際の各指標を計算することになります。 # コード例 import numpy as np import matplotlib.pyplot as plt # 正規分布に従う乱数を生成 ratios = [ 1 , 10 , 100 , 1000 ] sample_size_positives = 1000 positives = np.random.normal( 3 , 1 , sample_size_positives) dataset = {} for r in ratios: sample_size_negatives = sample_size_positives * r negatives = np.random.normal( 0 , 1 , sample_size_negatives) dataset[r] = (sample_size_negatives, positives, negatives) # ratio=1の場合 ratio = 1 _, positives, negatives = dataset[ratio] fig, ax = plt.subplots() ax.hist(positives, bins= 100 , color= "r" , alpha= 0.5 , label= "positives" ) ax.hist(negatives, bins= 100 , color= "b" , alpha= 0.5 , label= "negatives" ) ax.axvline(x=threshold_example, color= "g" , linestyle= "--" , label=f "{threshold_example=}" ) ax.legend(loc= "upper right" ) ax.title.set_text(f "{ratio=}" ) ちなみに、グラフにおける各指標のイメージは以下のようなものとなります。 再現率(Recall) = (点線右側の赤色部分の面積) / (赤色部分全体の面積) 偽陽性率(False Positive Rate) = (点線右側の青色部分の面積) / (青色部分全体の面積) 適合率(Precision) = (点線右側の赤色部分の面積) / {(点線右側の赤色部分の面積) + (点線右側の青色部分の面積)} まず、4つのパターンについて、ROC曲線をプロットしてみます。 ROC曲線はどのパターンについてもほぼ同じで、左上に張り付くような形をとっており、AUCはほぼ1に近い値を取っていることがわかります。つまり、ROC曲線はデータの不均衡性の影響をほぼ反映していないことがわかります。 上図の赤い点はそれぞれの曲線上での閾値1.5における点を示したもの # コード例 # ROC curve threshols = np.linspace(- 5 , 5 , 1000 ) threshold_example = 1.5 fig, ax = plt.subplots() ax.plot([ 0 , 1 ], [ 0 , 1 ], linestyle= "--" , color= "g" , label= "random" ) for i, r in enumerate (ratios): recalls = [] fprs = [] sample_size_negatives, positives, negatives = dataset[r] for j in range ( len (threshols)): recalls.append(np.sum(positives > threshols[j]) / sample_size_positives) fprs.append(np.sum(negatives > threshols[j]) / (sample_size_negatives)) ax.scatter(fprs, recalls, color=plot_colors[i], label=f "ratio={r}" , s= 3 ) # 閾値threshold_exampleの時のrecallとfpr ax.scatter( [np.sum(negatives > threshold_example) / sample_size_negatives], [np.sum(positives > threshold_example) / sample_size_positives], color= "r" , s= 15 ) ax.legend(loc= "lower right" ) plt.xlabel( "FPR" ) plt.ylabel( "Recall" ) 次に4つのパターンについてPR曲線をプロットしてみます。 PR曲線についてはROC曲線とは異なり、4つのパターンそれぞれで全く異なる曲線がプロットされており、ROC曲線と比較してデータの不均衡性の影響を反映しやすいことがわかります。 図の赤い点における同じ閾値1.5で見てみると再現率は全てのパターンで同じ値を取っていますが、適合率においてはデータが不均衡になるにつれて低い値を取ることがわかります。 上図の赤い点はそれぞれの曲線上での閾値1.5における点を示したもの # コード例 # PR curve fig, ax = plt.subplots() for i, r in enumerate (ratios): recalls = [] precisions = [] sample_size_negatives, positives, negatives = dataset[r] for j in range ( len (threshols)): recalls.append(np.sum(positives > threshols[j]) / sample_size_positives) precisions.append(np.sum(positives > threshols[j]) / (np.sum(positives > threshols[j]) + np.sum(negatives > threshols[j]))) ax.scatter(precisions, recalls, color=plot_colors[i], label=f "ratio={r}" , s= 3 ) # 閾値1の時の適合率と再現率 plt.scatter( [np.sum(positives > threshold_example) / (np.sum(positives > threshold_example) + np.sum(negatives > 1.5 ))], [np.sum(positives > threshold_example) / sample_size_positives], color= "r" , s= 15 ) ax.legend(loc= "lower right" ) plt.xlabel( "Precision" ) plt.ylabel( "Recall" ) 最後に 今回は2クラス分類における、データの不均衡性とROC曲線およびPR曲線の関係性について掘り下げてみました。 一般的にはモデルの性能評価にはROC曲線を用いることが多い気がしますが、PR曲線の存在も頭に入れておくと、不均衡なデータを扱う際に役に立つかもしれません。 一応適合率を扱う際の注意点を挙げておくと、検証用データにおける負例が本番のデータからダウンサンプリングされている場合、算出される適合率がそのサンプリング比率に依存してしまう点があります。 例えば負例が本番のデータから1/rの件数だけランダムサンプリングされている場合、実際の適合率へ補正する計算式としては、検証用データにおける偽陽性(False Positives)の件数をN(FP)などとして といった形が考えられます。負例が圧倒的に多いケースでは、状況に応じて分母のN(TP)を0に近似してしまって、検証用データにおける適合率に1/rをかけた値を真の適合率としてしまっても良いかもしれません。 また、実務においては偽陽性や偽陰性の数だけで評価するのではなく、その質や誤分類コストの非対称性などにも注意を払うことが重要です。不良品検知の例でいえば、偽陰性の中に深刻な欠陥を見逃している例がないか、不正決済の検知であれば大きな損害をもたらす決済を見逃している例がないか、といったサンプルごとに異なる誤分類コストについても十分吟味する必要があります。 最後となりますが、DataStragetyチームではBASEにおけるデータ分析基盤の改善を一緒に行っていくメンバーを募集しています。ご興味のある方は気軽にご応募ください! A-1.Tech_データエンジニア / BASE株式会社 明日のBASEアドベントカレンダーは @h7jin16 さんと @u_hayato13 さんの記事です。お楽しみに! 参考資料 Wikipedia,Receiver operating characteristic https://en.wikipedia.org/wiki/Receiver_operating_characteristic scikit-learn,precision_recall_curve https://scikit-learn.org/1.5/modules/generated/sklearn.metrics.precision_recall_curve.html Google,Machine Learning Crash Course,roc-and-auc https://developers.google.com/machine-learning/crash-course/classification/roc-and-auc?hl=en
アバター
本記事は BASE アドベントカレンダー 2024 の 22 日目の記事です。 はじめに こんにちは! BASE 株式会社 Pay ID 兼 BASE PRODUCT TEAM BLOG 編集局メンバー の @zan_sakurai です。 今年も残すところあとわずかとなりました。今年も多くの方に BASE PRODUCT TEAM BLOG ご覧いただき、ありがとうございました! 1 年間 BASE PRODUCT TEAM BLOG 編集局としていろいろな記事のレビューに関わらせていただきました。 この機会に改めて今年の記事を全て読み返したので、せっかくなので、今年の記事を振り返ってみたいと思います。 今年の記事を振り返ってみます 今年の投稿数は残りのアドベントカレンダーを含めると約 70 記事となりそうです。 BASE PRODUCT TEAM BLOG は、2016 年にスタートしていますが、 投稿数としては 2019 年の 93, 2021 年の 87 に次ぐ、3 番目に投稿数の多い年となりそうです。 有り難いことに執筆いただける方も増えており、技術に限らない、プロダクトマネジメント、マネジメント、採用、イベントレポートなど、幅広いジャンルの記事をお届けできたかと思います 今年の第一号は? 今年の記事は、竹本さんの YAPC:Hiroshima 2024 に参加しました から始まりました。 弊社 CTO の川口さんのスポンサー LT をはじめ、印象に残ったセッションをご紹介いただいており、幸先の良いスタートとなりました。 今年特にはてなブックマークをいただいた記事 今年特にはてなブックマークを頂いた上位 3 記事は以下となりました。 技術に限らない幅広いジャンルの記事をお届けした 1 年でしたが、特にはてなブックマークをいただいた記事は技術系の記事でした。 とてもわかりやすい記事ですので、まだお読みになっていない方はぜひご覧ください! explain だけじゃわからない!MySQL の index の考え方 OIDC って何なんだー?から、実際に使うまで AWS の DMS やブルー/グリーンデプロイを使って MySQL8.0 へ移行した話 イベントレポート・スポンサー・登壇に関する記事が多かった イベントレポート・スポンサー・登壇に関する記事が多かったように見受けられました。 さまざまなイベントに参加し、登壇やスポンサーをさせていただいたかと思います。 余談ですが、投稿いただいた記事以外にも社内での技術交流イベントもこれまで以上に活発に行われていたように感じた1年でした! Fullstack AI Dev & Raycast Summit にスポンサーしました! 社内 LT 会で半年間、毎月登壇をし続けた話 〜実際の登壇内容も添えて〜 BASE BANK, 中小規模のエンジニアイベントにも会場&飲食スポンサーします! Welcome Fintech Community #2 〜Fintech ドメインを深掘る LT 会〜を開催しました! Welcome Fintech Community #1 を開催しました! スクラムフェス大阪 2024 で BASE BANK のメンバーが 2 名登壇しました! PHP カンファレンス福岡 2024 に BASE BANK のエンジニアが登壇しました AWS Summit Japan 2024 に参加しました PHP カンファレンス小田原 2024 に BASE のエンジニアが登壇しました Object-Oriented Conference 2024 に参加しました PHPerKaigi 2024 に 2 名のメンバーが登壇しました PHP カンファレンス関西 2024 にコアスタッフとして参加しました YAPC:Hiroshima 2024 に参加しました 最後に ここでは紹介しきれないくらい多くの記事がありますので、まだお読みになっていない方はぜひ読んでいただきたいです...!!! 今年も多くの方にご愛読いただき、誠にありがとうございました。 また、来年も引き続き多くの方に読んでいただけるよう、記事の品質向上に努めてまいりますので、引き続きよろしくお願いいたします! また、BASE は現在エンジニア積極採用中なので興味があれば採用情報ぜひご覧ください! binc.jp 次回は kikuchi1201 さんの「PHP カンファレンス 2024 のスポンサーしました」が公開予定です。お楽しみに!
アバター
この投稿は BASEアドベントカレンダー2024 の21日目の記事です。 はじめに SRE Group でエンジニア?をしている@basemsです。 まだ入社して5ヶ月の若輩者です。 「エンジニア?」 という表現は、私の現状は技術そのものではなくチーム運営だったり業務改善といった方向に注力しているので、まだ 「BASEのエンジニアです!」 と自信を持って名乗る程ではないという心理の表れです。 本記事はエンジニアとしてというより、過去の経験からくるプロジェクトマネジメントの面が強い内容になっております。 この記事って何 私自身、BASE以前に何社か渡り歩いていますが、 PJ進行においてエンジニアと非エンジニア間の軋轢だったり衝突は大なり小なり発生しない方が稀 だと感じています。(部署の違うエンジニア間でもあったりする) が、その改善方法や心構えのブログ記事とかはネット上に存在はしてますが、体系立てて学ぶような研修やレクチャーといったものをやる会社はあまり聞かず、PMは元より関わるメンバーそれぞれが 実際に経験して身につけていってねといった傾向がある と感じています。 そこで「自身の頭の中を整理の為にアウトプットする」目的も兼ねて、まずは エンジニアと非エンジニアで同じ方向を向いてPJ進行する為の心構え 的な事を記事にしようと思った次第です。 堅苦しいタイトルになっていますが、 「この辺りを意識してお互い会話してみようよ」 といった内容なので、気軽に読んでいただけると嬉しいです。 当記事の内容は私の経験則なので、当然ながら異論・反論はあるものだと思います。 私自身がエンジニアなので逆の立場からすると 「いや、それは違うだろ」 といったご意見はあって然るべきだと思いますが、 それらをぶつけて改善し後進の為の教材作りができればいいな的に考えていますので歓迎します! (なのでタイトルも 仮 をつけています) ※ちなみに当記事の非エンジニアという括りは、だいたいディレクターやPM・PDMといった方を指しています。 役割が違うだけで上下はないという気持ち まずはざっくりと心構えの話です。 エンジニアと非エンジニア(ディレクターやPM・PDM)の関係性は会社によって違いがあるかと思いますが、上手くいっていないパターンは大体以下のどっちかだと感じます。 エンジニアが強過ぎて、非エンジニアが物申しづらい 非エンジニアが強過ぎて、エンジニアは従わざるを得ない 完全なパワーバランスというのは理想論だと思いますが、それでも 「役割が違うだけで対等な立場である」 という事を今一度心に留めましょう! 相手の意見や要望を”頭から”否定しない 「相手の意見を”頭から”否定しない」 ブレストなんかでは基本ルールだったりしますが、PJ進行においても心がけても良い事だと思います。 “頭から”というのは、まぁ無理なものは無理という状況は現実としてあり得るのですが、 その決断を出す前に 相手がその意見・要望を出した背景や根拠をはっきりしましょう・させましょう! 突っぱねたくなる無茶振りされた経験は大抵誰でもあるかと思います。 それに対して、 「期限的にムリだからできません」 「決まっている事だからやってください・間に合わせてください」 というスタンスだと意地の張り合いみたいな状況になってしまいますが、お互いの置かれている背景を知る事で何らかの糸口なりアプローチが見えてきたり、 エンジニア・非エンジニアというそれぞれの役割の中だけでは得られなかった、思わぬ気付きがあったりします。 すでに今までの経験で「言ってもダメだろう」的な諦めが入っている方もいるかもしれませんが、 こちらも前項と同じく改めて心に留めてみてください! やることの具体化と明確化 ここまでは心構えの話でしたが、ここからは具体的な進行の話です。 身も蓋もない言い方をするなら、プロジェクト進行は無期限じゃないのが普通な以上、 100%の理想を追いつつ関係者全員が飲み込める落とし所を見つける事の繰り返し だと思っています。 その為に 「やることの具体化と明確化」 という、 絶対に達成するべきライン(PJでやる事)をはっきりさせて意志統一をする 作業を行います。 エレベーターピッチがあれば、それを要件定義できるように要素を分解していくイメージです。 記事のテーマに沿って役割別の観点を加えるなら、 非エンジニア:PJをやる意義・やりたい事の具体化と明確化 エンジニア:やる事の輪郭(規模感)を掴む、実現性の「あたり」をつける こういった感じでしょうか。 これはエンジニア・非エンジニア問わず関係者全員が協力してやる事が重要で、 どちらかの観点がないと、大なり小なり 「顧客が本当に必要だったもの」 という有名なあのパターンにハマります。 はじめの一歩:最初に整理するべき項目 整理する項目をあげていきます。 誰が(発案か) 誰の為に 何をやりたいか(させたいか) いつまでに 何を(会社)得られるのか これらはPMやPDM・ディレクターの方は理解しているとは思いますが、 エンジニア側が知る事で、より良い要件定義や設計ができるはずです。 (断言) 項目毎に説明してきます [誰が(発案か)] プロジェクトの発端が 「誰・どこ」から出てきたものか を明確にします 。 この「誰・どこが」によって、他の情報が持つ意味合いが変わってくる事もあります。 「いつまでに」 という項目も、身も蓋も無い言い例を挙げると 不特定多数のユーザーからの要望 →   背景を確認しつつ、なるはやで進めるべき 重要クライアント →   期限は動かせない前提で考える 社内発案の施策 → ある程度の調整はききそう と、この様に温度感が変わってきますし、エンジニアの考え方・動き方も相応に変わるはずです。 (あくまで例なので、社内発案の施策が常に温度感高くないとかじゃ無いです!) また、ここで 「要件や仕様の承認あるいは最終判断をできるのは誰か」 もはっきりしておきましょう。 プロジェクトに対して誰と誰が裁量を持っているかを全員が知る事で、エンジニア・非エンジニアだけでなく部署間の連携もやりやすくなるはずです。 ※プロジェクトの責任の所在がどうこうでは無いので注意 [誰の為に] このプロジェクトのターゲットをはっきりさせましょう + それを可能な限り詳細に掘り下げましょう。 例えば「ショップオーナーさん」をターゲットにしたBASEの新しい機能の提供を考えるとします。 単なる「ショップオーナーさん」だけでは不十分 で、そこから 既存機能を使い慣れている人向け 新規に開設する人にも積極的に使ってもらいたい このどちらであるかを明確にする事で、考慮するべき内容 (エンジニア視点だと特にUI、UX) は大きく変わるはずです。 特に b の要素があるのに取りこぼすと 本当に使ってもらいたい人に使ってもらえないという悲しい結果になります。 [何をやりたいか(させたいか)] 今回のプロジェクトで 達成したい事・ターゲットに何を提供したいかを明確にして、関係者全員の認識を合わせましょう。 そして、それを実現する為に何が必要かを詰めていきましょう。 エンジニアは漠然と 今の手持ち(開発環境やシステム・インフラ等々)での実現性を考えます。 足りない要素があれば整理し、必要であれば課題提起しておきましょう。 (新規か改修か? 社外が絡む要素はあるか? 人以外のコストが発生するのか? 等々・・・) 例えば「AIを使って何かやりたい」という要望があったりしますが、 「そのAIはどこから持ってくるの?」とか「AIに学習させるデータや素材は?」とかが白紙だったりするので、 エンジニアはそういった点を提起しプロジェクトの課題として明確にします。 非エンジニアの方は、こういったエンジニアの指摘は細かいなぁと思われるかもしれませんが、 プロジェクト完遂の為に避けて通れない課題を早めに把握しておく為 と思ってお付き合いください。 [いつまでに] 具体的な日程だけではなく、 その性質をはっきりさせましょう。 ざっと思いつくレベルですが、以下は明確にしておくべきだと思います。 絶対にずらせない or 調整が効くのか 絶対にずらせない場合は、その理由 社外との連携はあるのか 間に合わない場合にどういう不利益を被るのか エンジニア視点だと、前項までの情報から明らかにスケジュールに無理があると判断できるパターンがあったりするかと思います。 そういった時は 非エンジニアの方にも無理な要因を理解してもらい、共通認識を持ってもらう必要があります。 私の場合ですが、以下のように3つの方針で情報整理しています。 プロジェクトを100%達成し、かつスケジュールに収める為に必要な事 お金とか増員とかでなんとかなるならという前提 お金はともかく、 人を”いきなり”倍に増やしても工期は半分にはならない ( 重要) 無理なら無理な理由を徹底的に整理する プロジェクトの100%達成を優先する場合に、絶対必要なスケジュール スケジュールに収める事を優先する場合に、犠牲にしなければならない事(要件や機能) PMの領域に踏み込んでる気もしますが、実装の規模感を知っているのはエンジニアだと思うので、この辺りは PMと協力して考えてみるべきだと思います。 [それにより何を(会社が)得られるのか] 売上だったりユーザー獲得だったりといった、 このプロジェクトが成功すると何を得られるのかをはっきりさせましょう。 直接的な利益ではなくとも サービスの安定性・信頼性の向上も得られるもの として捉えます。 エンジニア視点ではこの要素も重要で、 特に設計においては一つの指標となります。 ユーザーの獲得が目的なのに、スケジュールの都合で 快適性を損なうUIやUXで実装したり 、 売上が出ることを見込めたとしても、 それを帳消しにするようなランニングコストが発生します というのは本末転倒です。 プロジェクトの成果がどう出るのかは全員のモチベーションとなると思うので、これも認識を合わせておきましょう。 おわりに 長々と書いてきましたが、この内容はスタートラインです! 書ける事はまだまだあるので、機会があれば続きを書ければ良いなぁと思っています。 BASEでは幅広い職種で新しいメンバーを募集しております。 興味持たれた方は、カジュアル面談からでもぜひご応募ください! 採用情報 | BASE, Inc. - BASE, Inc. 明日は @zan_sakurai さんの記事です! お楽しみに!
アバター
はじめに この記事はBASEアドベントカレンダーの21日目の記事です。 こんにちは!BASE株式会社でPay IDチーム プロダクトマネージャーグループのマネージャーをしているkumaです。 Pay IDは、BASEで作られたショップでのお買いものを楽しむためのショッピングサービスで、クイックでスムーズな決済機能と、ショッピングアプリを提供しています。 本記事ではフィンテックドメイン未経験からフィンテックプロダクトのPMを1年半ほど経験して感じた 「プロダクトマネージャーとして何でも面白がる、面白がり力」 の重要性を話します。 ドメイン知識を身につけるのはなかなか大変 プロダクトを成功させるためにPMとして必要なスキルや経験は様々ありますが、その中でも「ドメイン知識を身につけること」は重要な要素のひとつです。 しかし、ドメイン知識を習得するのは容易なことではありません。 座学や業界調査、顧客インタビュー、社内外の専門家との連携、勉強会やコミュニティへの参加など、方法は多岐にわたりますが、いずれも時間と労力がかかります。 そして、これを「やらなければならない義務」として捉えると、なかなかの苦痛を伴う作業になりかねません。 特に、もともと興味関心の薄いドメインや未経験の業界に飛び込む場合、その苦痛は一層増すでしょう。 急に未知のドメインに飛び込む可能性は、誰にでもある しかし、例えば新規事業の立ち上げや部署異動、マルチプロダクト間での担当プロダクト変更、さらには転職など、PMが 全くこれまで興味関心を持っていなかった、新しいドメインを担当する機会は誰にでも訪れる可能性があります。 では、そんな時にどのようなマインドで取り組むと、ポジティブにドメイン知識の習得に取り組んでいけるのでしょうか。 フィンテック未経験から決済関連のプロダクトマネージャーへ 私自身の話をすると、現在、BASE社にてコンシューマー向けのプロダクトマネジメントを主に担当しています。 そのなかでもワンクリックで簡単にクレジットカード決済ができるID決済や、Pay ID あと払い(いわゆるBNPL)という決済プロダクトを主に担当しています。 最近では分割払いの機能をリリースしました。 binc.jp これまでフィンテック業界でゴリゴリPMをやってたかでいうと全然そんなことはなく、 BASEに入ってから初めて経験しました。 私が入社した直後にあと払いのプロダクトがサービスインし、PMとしてアサインされたという経緯でした。 なので、特段フィンテックにとても興味がある状態から入ったわけでもありませんでした。 未経験で飛び込んだこの領域では、複雑なビジネスモデル、関連法令、契約形態など、これまで生きてきた中で一度も触れたことがないようなドメイン知識を理解しつつプロダクトづくりに取り組む必要が出てきました。 一例:クレジットカード業界のビジネスモデル。謎のワードや概念が飛び交う Credit Cardビジネスモデル 画像は以下から引用 https://www.kantei.go.jp/jp/singi/keizaisaisei/miraitoshikaigi/sankankyougikai/fintech/dai1/siryou2.pdf 「どんなことでも面白がる」というマインドセットがあれば、PMはどんなドメインでもやっていける アサインされた当初はこの複雑さに後退りしそうになりましたが、1年半ほどたった今では、同じチームの決済ドメインの業界歴が長いメンバーに「未経験からなんでこんなにやれてるのか謎ですごい」という言葉を頂けたくらいには、 やっていけてます。 なぜそうなれたか振り返ってみると 「どんなことでも面白がる」というマインドセット があったからこそ、だと感じています。 「どんなことでも面白がる」というマインドセット、 「面白がり力」 は言い換えれば 「未知の領域に対して怯えず好奇心を持ち、動きながら考える。そして自分に意味付けしてモチベーションを引き出す力」 だと考えています。 私が考えるこのマインドセットを持つために意識していた3つのポイントを紹介します。 ①:動きながら考える 分からないこと、未知のものに取り組むことは、不安だし腰が重くなります。 つい座学で色々勉強してから、動こうとしてしまいがちです。 私の場合は、特に「決済とは」「あと払い(BNPL)とは」のような研修等は特になく、いきなり実戦投入でした。 でも振り返ると、 分からないながらもとにかく動き回って実際のものごとに触れながら考えたほうが、結果得るものが大きかった と感じています。 やっていくと自然と疑問が湧き出てくるので、都度その疑問を解消していけば、自ずと身についてきます。 ②:分からない状態であることをポジティブに捉える ピュアに 何も「分からない・知らない」状況は最初しかない です。 どんどん知識がつくにつれて良くも悪くも業界に染まっていきます。 無知だからこそ感じる、 業界への純粋な違和感は最初にしか味わえず、ここで感じた違和感が今後のプロダクトづくりに活かせる ので、この状態をポジティブに捉えましょう。 私の場合、とあるアイデアに対しドメインエキスパートのメンバーから「その発想は業界の慣習的にはなかったが、ありかもしれない」と言われたことが何度かあり、プロダクトに取り込めたものもあります。 無邪気に物事を考えられる状態は貴重だと感じています。 ③:自分の興味関心とリンクする部分を発見し、自分に意味付けをする 私の場合、最終的には自分の興味関心や価値観とリンクしないと、継続的にモチベーション高く取り組むことがなかなかできないタイプです。 そのため、発見していく物事に対して、 自分の興味関心や価値観とリンクする部分を見つけて、自分がなぜそれをやるのか、自分に意味付けをすることで、モチベーション高く 取り組むことができます。 私の場合は、決済のことを知っていくうちに、決済は人類の歴史のなかでも大きな発明であることを実感し、これから自分たちが新しい「決済」を作っていくことは、人類の進化に貢献できると感じ、モチベーション高く取り組むことができています。 「面白がり力」があれば、どんなドメインでもPMとしてやっていける このように「どんなことでも面白がる」というマインドを持つことで、ドメイン知識を得る過程が苦痛ではなく、楽しいものに変わると考えています。 ①動きながら考える ②分からない状態であることをポジティブに捉える ③自分の興味関心とリンクする部分を発見し、自分に意味付けをする こうしてみると、割と当たり前のことを言っていますが、このマインドセットがあれば様々な未経験のドメインのプロダクトでもPMとしてやっていけると私は思っています。 最後に もしこの記事を読んで「私も未知の領域に挑戦してみたい」と思っていただけたなら、その第一歩を踏み出す手助けになれば幸いです。 また、私たちも現在Pay IDチームではプロダクトマネージャーを絶賛募集中です! 現在在籍しているPMは私のようにフィンテック未経験のメンバーが多いです。 所属するチームにはドメインエキスパートの方々もいらっしゃるのでとても心強いチームとなっています。 ご興味あればぜひ一度、お話からでも聞いていただけると嬉しいです! open.talentio.com 採用情報 | BASE, Inc. - BASE, Inc. 次回はPay ID ID決済グループのzanさんの記事が公開予定です。お楽しみに!
アバター
はじめに 本記事は BASEアドベントカレンダー2024 の20日目の記事です。 Pay IDのフロントエンドエンジニアをしているnojiです。 以前執筆した  システムリニューアルでNext.jsのApp Router/Server Actionを使って便利だと思ったところ  に記載したように、Pay IDのアカウント管理画面ではNext.jsを採用し、Server Actionを活用しています。 今回は、そのServer Action導入時に行ったフォームバリデーション周りの取り組みについて紹介します。 react-hook-formを使ったフォームバリデーション アカウント管理画面の特性上、ログインだけでなく名前や住所など登録情報の編集といったフォーム操作が必須です。そのため、以下の要件を満たすフォームバリデーションが必要でした。 入力中 or 入力後にエラーを検出し、ユーザーに即座に通知できる Server Action実行前にクライアント側でバリデーションが実施できる。また、その際に追加処理を挟む柔軟性がある バリデーションエラー処理を簡潔に実装できる これらを実現するため、BASEでも採用実績がある react-hook-form を使うことにしました。 しかし、react-hook-form自体は12/16現在でServer Actionをサポートしているわけではありません。 そこでBETA版の Formコンポーネント を利用し、バリデーション処理とServer Actionの両方を実現できるような実装を行いました。 react-hook-formのFormコンポーネントを利用したフォームバリデーション 従来のreact-hook-formを利用したフォームバリデーション実装は以下のように記述します。formタグのonSubmitにhandleSubmitを渡すことでバリデーション成功時に引数のonSubmit関数が呼ばれます。 const { handleSubmit } = useForm(); const onSubmit = ( data ) => { // 処理 } ; < form onSubmit = { handleSubmit(onSubmit) } /> これを、BETA版の Formコンポーネント を使用することで次のように書き換えられます。 < Form onSubmit = { ( { data , formData , formDataJson , event } ) => { // 処理 } } /> onSubmitはバリデーション成功時に呼び出される関数として機能します。引数には、オブジェクト形式、FormData形式、JSON形式でフォームデータを受け取れるため、柔軟な処理が可能になります。 Formコンポーネントには他にもいくつかpropsの項目が用意されているので、気になる方は ドキュメント をご確認ください 実装例 Server Actionとの連携 Server Actionは、 useActionState を組み合わせて使用します。フォームのアクション結果に基づきstateを更新してくれるhooksになります。また、バリデーションスキーマには  zod  を採用し、サーバー側とクライアント側で共通化しました。 以下は、Server Actionとフォームバリデーションの実装例です。 バリデーションスキーマの定義例 // schema.ts export const schema = z.object( { email : z.string() .min( 1 , 'メールアドレスを入力してください' ) .email( 'メールアドレスの形式が正しくありません' ), } ); Server Actionの実装例 // server-action.ts export const serverAction = async ( prevState : any , formData : FormData ) => { try { const data = schema.parse( { email : formData. get ( 'email' ), } ); await fetch ( 'https://backend-api-example.com/v1/hoge' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' , } , body : JSON . stringify (data), } ); redirect( '/complete' ); } catch (error) { return { code : 'server_error' , message : 'エラーが発生しました' , } ; } } ; Formコンポーネントの実装例 // form-client-component.tsx 'use client' ; import { useActionState } from 'next/server-actions' ; import { useForm } from 'react-hook-form' ; import { zodResolver } from '@hookform/resolvers/zod' ; import { schema } from './schema' ; const FormClientComponent = () => { const [ state , formAction , isPending ] = useActionState(serverAction); const { register , control , formState : { errors } , } = useForm( { resolver : zodResolver(schema) } ); return ( < div > { state?.message && < p > { state.message } </ p > } { /* サーバー側エラーメッセージの表示 */ } < Form control = { control } onSubmit = { ( { formData } ) => formAction(formData) } > < label htmlFor = "email" > メールアドレス </ label > < input { ...register( 'email' ) } type = "email" id = "email" /> { errors.email && < p > { errors.email.message } </ p > } { /* クライアント側バリデーションエラー表示 */ } < button type = "submit" > 送信 </ button > </ Form > </ div > ); } ; FormコンポーネントのonSubmit内でServerActionを実行するようにしています。 Formコンポーネントのpropsでactionも渡すことができるのですが、このactionについては fetchを呼び出すため のもののようで、現状formActionを渡してもServerActionをうまく実行できなかったので使わないようにしました(今後はここが修正されてactionで実行できるようになるかもしれません) カスタム処理の追加例 onSubmit内で非同期処理を実行し、formDataをカスタマイズすることも可能です。 onSubmit= { async ({ formData } ) => { const token = await getToken(); formData. append ( 'token' , token); formAction(formData); } } 使ってみての感想 ServerActionとreact-hook-formのFormコンポーネントを組みわせることで以下の部分が便利だと思いました。 FormコンポーネントのonSubmitがバリデーション成功時しか呼ばれないため、バリデーション制御処理をすべてreact-hook-form側に寄せることができたこと。また、ServerAction実行前にformData等に値を追加したりクライアント側で非同期処理を呼び出したりできること。 useActionStateを利用していることで、onSubmit内でServerActionを呼ぶだけでよく、レスポンスのハンドリングや状態管理についてクライアント側で考えなくて良くなったこと。 おわりに 現時点では、react-hook-formのFormコンポーネントはBETA版のため注意が必要ですが、将来的にServer Actionを完全サポートする可能性も考えられます。その際には今回の実装をさらに簡略化できるかもしれません。今後も動向をウォッチしながら改善を進めていければと思います。 Server Actionとreact-hook-formの連携について紹介しましたが、皆さんのプロジェクトの参考になれば幸いです。 最後に、Pay IDではエンジニアを募集しています。興味がある方はお気軽にご応募ください! 採用情報 | BASE, Inc. - BASE, Inc.
アバター
この記事は BASEアドベントカレンダー2024 の19日目の記事です。 同じく19日目には住所の奥深さを知れる Pay IDのエンジニアの金子さんの記事 も公開されていますので、ぜひご一緒にお楽しみください! 自己紹介 プロダクトデザイナーの ichi です。BASEに入社してから21ヶ月が経ち、入社時からBASE BANKチームの一員として金融プロダクトの開発に取り組んでいます。 社内では「お祭り小僧」として、会社主催の忘年会やチーム懇親会の幹事として企画や運営を担当したり、イベントに参加しやすい雰囲気づくりを心がけてきました。 また、今回のアドベントカレンダーのOGP画像もその一環で制作協力させていただきました! 自分が関わるチームのコミュニケーションをスムーズにし、チームをつなぐ「場」の設計に力を注いでいます。 今回は、そんな私がBASE BANKチームで行ってきたチームビルディングの取り組みについてお話しします。 BASE BANKチームについて BASE BANKチーム は、「個人やスモールチームの金融をかんたんにし、挑戦がめぐる世の中に」をミッションに掲げ、金融プロダクトの開発を通じて、ユーザーにとって価値のあるサービスを届けることを目指すチームです。アジャイルな開発体制が特徴で、個々の強みを活かしながら日々プロダクト開発を行っています。 今回のアドベントカレンダーでも何人かメンバーが記事を投稿しているので、よかったらみてみてください〜! Day04 | 若手エンジニアがBASE入社6ヶ月目で感じていること Day11 | 技術目線でみた、PAY.JP YELL BANKのおもしろいところをご紹介! Day12 | 私のキャリアチェンジ:データ分析者からプロダクトマネージャーへ Day20 | 登壇やアウトプットを後押しするnote アジャイル組織のデザイナーとしてのチームビルディングの取り組み 私が取り組んできたチームビルディングの具体例を紹介します。 1. Slack絵文字を活用した自己紹介の場づくり 今まで登録してきたslack絵文字 BASEのSlackチームスペースにはSlack絵文字が5000以上存在し、コミュニケーションに欠かせない文化です。私も現在までに、私は75個以上のSlack絵文字を作成してきました。 入社3日目にまず行ったのは、自分のアイコンのアニメーション絵文字を3種類作ることでした。これによって同僚に覚えてもらいやすくなり、これをきっかけに、「あのアイコンの人だ」「何持ってるの?きりたんぽ?」とはなしかけてもらえて、初対面の人との会話やつながりも自然と生まれました。 アニメーションgifについては、元々自己紹介ツールの一環として LINEスタンプ を作成していたので、腕だけ動かすアニメーションを作るのはそこまで大変ではなかったです。 2. Figma勉強会での知識共有 入社5ヶ月目には、BASE BANKメンバーを対象にしたFigma・FigJamの勉強会を開催しました。「デザイナーだけが使うツール」だと思われがちなFigma・FigJamを、チーム全員がスムーズに使えるようサポートする取り組みです。 これにより、デザイナーと非デザイナーの間で共通言語が生まれ、プロジェクトの効率も少しは向上したと思います。現在はFigJamをデザイナー以上に使いこなす非デザイナーがたくさんいます。 また、この内容は後日ドキュメント化して、入社時のオンボーディングタスクに組み込みました。 3. 入社オンボーディングクエスト 入社10ヶ月目ぐらいの時に、自分がメンターをする機会があったので、新入社員が入社した際のタスクリスト…通称【入社オンボーディングクエスト】をNotion上に作成しました。膨大な情報量の中で何を優先してインプットするべきかを明確にすることで、新しいメンバーがスムーズにチームに馴染めるようサポートしました。 もとになった神テンプレート をBASE BANK用にカスタマイズし、すでに結構な新入社員・異動社員メンバーに使われています。その度にドキュメント情報をメンターになったメンバーがアップデートしてくれているため、完成度が上がりすぎたフォーマットに。 最近はBASE BANKチーム以外にも広がり、現在はプロダクトDevチームのオンボーディングでも転用されています。 4. ストレングスファインダーを活用したチーム理解 ストレングスファインダー というツールを使い、チームメンバーの特性を可視化するためのフォーマットと、ワークショップの場作りをしました。これにより、メンバーそれぞれの強みが可視化され、仕事の依頼の仕方や、逆に協力して欲しいことなどがシェアできました。 実際に作ったワークショップ用フォーマット(左)と、実際に行われたチームで共通点を見る作業(右) 超有料級のフォーマットになって大満足です。何よりも、ただストレングスファインダーを受けてもらうだけではなく、それをチームとしてどう活かせるかを考えて作ったワークショップがめっちゃ盛り上がってくれたのは感動しました。 詳しくはこちらをご覧ください! basebook.binc.jp 5. ふりかえりの文化醸成 ふりかえり(retrospective)は、入社4ヶ月目から現在まで、私が特に力を入れてきた活動です。最近はふりかえりを強化するような野望(BASE BANK 独自用語。個人目標みたいなもの)を掲げてさらに頑張ってます。 当初、ふりかえりは「なんとなく必要だから」ぐらいの温度感で、チームによって行われていたり、行われていなかったりしていました。 自分は元々「 ファシリテーターを必要としないふりかえりツール 」の開発をしていたことから、チームのふりかえりの底上げが必要だと感じ、FigJamを使ったふりかえりのためのフォーマットの作成やファシリテーターとしての活動を通じて、より価値あるプロセスに進化させました。 最近では、「ふりかえりエヴァンジェリスト」を名乗りチーム向けにふりかえり勉強会を開催し、「ふりかえりの目的や価値」を共通言語にすることで、チーム全体の共通認識を深める活動を行いました。 ふりかえり勉強会 これも超有料級の勉強会になったとおもいます。 実際に目論見通りふりかえりの価値がチームの共通言語にすることができたと思っているし、この勉強会をするにあたって結構調べて作ったので、今度改めて記事にできたらいいなと思ってます。 ふりかえり勉強会の様子 そしてこれからも草の根活動としてふりかえりの継続的な改善を続け、ふりかえりがチームの成長を支える文化としてしっかり根付くよう取り組んでいきます。 まとめ 自分はBASE BANKチームを、個人の個性を最大限に活かせる組織にできたらいいなと思っています。デザイナーとしての視点を活かしながら、チームビルディングに取り組んできました。 その中で、以下の点を意識して活動しています。 メンバーの個性を最大限に発揮できる場を作る ホスピタリティを持って場を作る ワークショップを主催する際は参加メンバーの工数を最小限に抑え、最大の成果を目指す 作成したツールは継続的にアップデートする デザイナーの強みは「誰でもわかるもの」を作れることです。 この強みを活かして、これからもチームの成長を支える場やコミュニケーションツールの開発を続けていきます! 明日の担当は…… BASE BANK事業責任者のyanagawaさん PayIDのフロントエンドエンジニアのnojiさん のお二人の記事が公開予定です。 おたのしみに! join us! 絶賛採用活動中です! まずはお気軽にカジュアル面談しましょう〜🙌 採用情報 | BASE, Inc. - BASE, Inc.
アバター
本記事は BASEアドベントカレンダー2024 の19日目の記事です。 はじめに こんにちは、Pay IDのエンジニアの金子です。普段は「Pay ID あと払い」の決済サービスのバックエンドを中心に開発を担当しています。 10月末に「 Pay ID 3回あと払い 」の機能をリリースしました。「Pay ID 翌月あと払い」に続き、新たな決済手段として使用可能になっています。 今回は、Pay ID 3回あと払い機能の実装をきっかけに住所の深さを知ることになったので、それについて話せればと思います。 Pay ID 3回あと払いとは 「Pay ID 3回あと払い」とは、Pay IDアカウントでのお買いものを、分割手数料無料で3回に分けてお支払いいただける機能です。月々のお支払い負担を軽減しながらお買い物を楽しむことができます。 https://payid.jp/blog/3pay より この機能の利用にあたっては、 ショップの「Pay ID 3回あと払い」の審査 購入者の「Pay ID 3回あと払い」の審査 が必要になります。 いずれも分割払いを使用するための審査となっていて、BASEから外部サービスに連携し、審査依頼を出しています。 住所問題 2023年、デジタル大臣が住所の表記ゆれにAIを使用して解決するといった趣旨の発言を発端に、「日本の住所がヤバい」問題がトレンド入りしました。当時の私はそこまで深く考えず、ふ〜んくらいにしか思っていなかったのですが、今回そのヤバさを少し垣間見ることになりました。 ショップ審査にあたっては、規約に同意のもと、ショップ情報を外部サービスへ連携する必要があります。そのうちの1つに「住所」の連携がありました。 ここで住所をそのまま連携できれば良かったのですが、BASEの住所は、都道府県以下が1つのカラムにそのまま保存されています。一方で、連携先には都道府県以下の住所を「市区町村(address1)」「丁番地以下(address2)」のように分割して送る必要がありました。 例えば、BASEの住所は、 〒106-6237 東京都港区六本木三丁目2番1号 住友不動産六本木グランドタワー 37F となっているので、BASEのテーブルのaddressカラムには「港区六本木三丁目2番1号 住友不動産六本木グランドタワー 37F」が入っています。 これを「港区六本木」「三丁目2番1号 住友不動産六本木グランドタワー 37F」のように連携する必要がありました。 住所分割のイメージ図 これを実現する方法としては、 ケンオールの郵便番号検索API や 郵便番号データ 等から、郵便番号を元に「市区町村」「町域」を取得し、一致するところまでで区切るといった対応があります。BASEでは独自の住所ライブラリを作っており(データ元は郵便番号データと同様)、これを使用して住所分割を行いました。 市区町村(address1) → 「市区町村」& 「町域」 丁番地以下(address2) → それ以下 「市区町村」「町域」とショップが入力した住所が完全一致とならない場合は、前方一致で一致するところまでを「市区町村(address1)」とし、住所不備の場合はショップに住所情報を確認してもらうといったフローで実現することができました。実装自体はこの仕様で進めることができたのですが、これをきっかけあることを知りました。 1つの郵便番号に複数の「都道府県」「市区町村」「町域」が紐づく住所が存在する 恐らくこれは住所について少し知っている人からすれば当たり前すぎることかもしれないのですが、私はそれまで全く知らずに生きてきました。そして自分が住所の初心者であることを自覚しました。 せっかく住所の入り口に立てたので、その深さを味わいたくなり興味半分で少し調べてみました。以降の説明は2024年12月12日時点の郵便番号データを元に調査したものになります。 (データ元: https://www.post.japanpost.jp/zipcode/dl/kogaki-zip.html ) 前提として、住所は郵便番号検索をすると大きく分けて「都道府県」「市区町村」「町域」と分かれて表示されます。 よくwebサイトで郵便番号を入れた際に自動補完されるのは、郵便番号から「都道府県」「市区町村」「町域」を特定できるためです。この際、1つの郵便番号に対して複数の結果が出てくる地域が存在するということになります。 1つの郵便番号に複数の町域が紐づくケース 1つの郵便番号に複数の「町域」が紐づくパターンがあり、このケースに該当する郵便番号は1,548件も存在することが分かりました。全体の約1.3%に当たります。 以下の表に紐づく町域が多い順TOP3を並べていますが、 452-0961 の「愛知県清須市〜」にはなんと 66の町域が紐づいていました 。 紐づく町域の多い順 TOP3 郵便番号 都道府県 市区町村 町域 紐づく町域数 452-0961 愛知県 清須市 春日明河原、春日一番割など 66 480-1103 愛知県 長久手市 岩作石田、岩作井戸ケ根など 65 441-0302 愛知県 長久手市 御津町下佐脇、御津町下佐脇新屋など 46 1つの郵便番号に複数の市区町村が紐づくケース 今度は、1つの郵便番号に「市区町村」が紐づくケースです。「町域」よりも1段階大きい括りになります。このケースに該当する郵便番号は134件存在し、全体の約0.1%でした。 紐づく市区町村の多い順 TOP3 郵便番号 都道府県 市区町村 紐づく市区町村数 950-0000 新潟県 新潟市江南区、新潟市西蒲区など 6 861-0000 熊本県 熊本市西区、熊本市東区など 5 636-0000 奈良県 生駒郡三郷町、生駒郡平群町など 4 1つの郵便番号に複数の都道府県が紐づくケース 驚きだったのが、 1つの郵便番号で複数の都道府県が紐づく地域 が存在しました。郵便番号を入れただけでは都道府県を特定できないということです。これらの地域の場合、郵便番号入力後の自動補完に頼らず全て自分で入力しなくてはなりません、大変です。このケースに該当する郵便番号は3件で全体の約0.002%でした。 紐づく都道府県の多い順 郵便番号 都道府県 紐づく都道府県数 498-0000 愛知県、三重県 2 618-0000 京都府、大阪府 2 871-0000 大分県、福岡県 2 超高層ビル番号 今までのとは対照的に、 1つのビルで複数の郵便番号を持つ場所 もありました。このケースは同じビルにありながら階層によって郵便番号が異なります。 郵便区番号が3けたの郵便区内に所在し、配達物数が特に多い超高層ビル(テナントビルに限ります。)については、ビルと階層を表す郵便番号を設定することがあります。 引用: https://www.post.japanpost.jp/zipcode/zipmanual/p04.html 例えば、新宿区にある西新宿パークタワーは1つのビルに対して53の郵便番号が紐づいていました。 西新宿パークタワーから一部抜粋 郵便番号 都道府県 市区町村 町域 163-1001 東京都 新宿区 西新宿新宿パークタワー(1階) 163-1002 東京都 新宿区 西新宿新宿パークタワー(2階) 163-1003 東京都 新宿区 西新宿新宿パークタワー(3階) 163-1004 東京都 新宿区 西新宿新宿パークタワー(4階) 1つの郵便番号で都道府県を跨ぐ地域があるかと思えば、1つのビルに対して複数の郵便番号が紐づく場所もあるといったように、単純に郵便番号と地域が1対1の関係ではないということが分かっていただけたかと思います。 これまでの事例は、郵便番号を元に住所を分割したいとなった際に問題になりそうな例で、「日本の住所がヤバい」と言われている所以はもっとあります。 春日部市八丁目〜の「八丁目」は固有名詞 兵庫県明石市の「和坂」は隣接する地域でありながら「かにがさか」と「わさか」と読む地域が存在する などなど…ここから先に足を踏み込むと更に険しい山道が続いていそうなので、この辺りで身を引くことにします。 おわりに 現状の住所分割に関しては、1つの郵便番号に複数の地域が紐づいているケースは件数が多くないこともあり、手動で対応をしていますが、今後システムで解決できるように調整していく予定です! 最後に、Pay ID では一緒にプロダクトを作るメンバーを募集しています。興味のある方はぜひ採用情報などもご覧ください。 binc.jp 明日はnojiさん、yanagawaさんによる記事です。お楽しみに!
アバター
この記事は BASEアドベントカレンダー2024 の18日目の記事です。18日目は shota.imazeki さんの記事( INFORMATION_SCHEMAを用いたBigQueryデータ監視 - BASEプロダクトチームブログ )も公開されていますので、ぜひご一緒に読んでみてください。 はじめに こんにちは、はじめまして。BASE の Feature Dev1 Group でバックエンドエンジニアをしている @meihei です。 2024年6月に入社してから半年が経ち、この間に多くの経験を積ませていただきました。 この記事では、私の日常の開発業務、特にローカル環境で PHPUnit を自動的・継続的に実行している方法についてお話しします。 息を吸うように PHPUnit を実行する さて、具体的に何をしているかと言うと、PhpStorm で PHPUnit 実行後の「Rerun Automatically」をオンにしています。 これにより、ソースコードを変更すると自動的にテストが再実行されるようになります。 つまり、コードを書いて一息つくたびにテストが実行される状態です。 symfony/demo を使って自動的にテストが再実行している様子 どうやって実現するのか 息を吸うように PHPUnit を実行するためには、PhpStorm でのテストが実行される設定をする必要があります。また、テストが高速で実行される環境も必要不可欠です。 PhpStorm でテスト実行を設定する Edit Configuration でテストに名前をつける PhpStorm の「Run/Debug Configuration」から「Edit Configuration」を開くと、新しいテスト実行の設定ができます。 www.jetbrains.com または、▶ Run ボタンを押すだけで、自動的に名前がついたテストを実行できます。 compound で複数のテストをまとめる compound 機能を使うと、複数のテストを同時に実行できます。 www.jetbrains.com これは、異なる phpunit.xml のテストを同時に実行したい場合や、特に遅い部分のテストを並列実行したい場合に便利です。 テストの実行速度を高速化する テストの実行速度を上げることで、開発効率が向上します。実行速度を向上させるには「テスト自体を高速化する」「実行するテストの量を減らす」という2つの方法があります。 テスト自体を高速化するには、テストケースをシンプルに保ち、スタブやモックを適切に活用します。 実行するテストの量を減らすには、テスト実行のスコープを狭めたり(詳細は後述)、型やバリューオブジェクトで制約を表現して不要なテストを避けたり *1 します。 テスト実行の適切なスコープを設定する テストの実行速度を上げるには、スコープを適切に狭めながら、必要十分なテストカバレッジを維持することが重要です。 単体テストの適切なスコープは一概に決められませんが、モジュラモノリスを採用している BASE では、1モジュール単位のテストが適切だと考えています。 そのため、私はモジュールごとのテストディレクトリ単位でテストを実行しています。 BASE大規模リアーキテクチャリング / base_rearchitecturing - Speaker Deck スコープを狭める他の方法として、ディレクトリ単位での実行や、 phpunit.xml の testsuites での設定も可能です。 テストを常に実行するメリット 最速でコードの不具合を検証できる PHPUnit を自動的に再実行する最大のメリットは、実装フェーズ以降で、 最速でコードの不具合を検証できる ことです。 これは Shift-left アプローチに通じています。 Shift-left とは、QA(Quality Assurance)の役割を開発プロセスの前方(左側)に移動させる考え方です。不具合の修正は開発プロセスの後工程になるほどコストが大きくなるため、できるだけ早い段階で不具合を発見し、早期にテストを実行することが重要です。 engineering.linecorp.com Shift-left の厳密な定義とは若干異なりますが、できるだけ早期にテストを実行したいという考え方は同じです。 実装フェーズ以降でテストを実行する最速のタイミングは コードを書いた直後 です。PHPUnit の自動再実行によってこれが実現できます。 自然とコードとテストをセットでコミットする これは副次的なメリットですが、自動的なテスト実行により、自然とコードとテストをセットでコミットするという良い習慣が身につきます。 *2 *3 なぜコードとテストをセットでコミットするようになるのかというと、コードを書いた直後に自動的にテストが実行されることで、 git commit を行う前にテストの結果を必ず確認することになるからです。 さらに、テストが失敗している状態ではコミットできない(心理的な)制約が生まれ、テストが通過することを確認してからコミットすることで、後から予期せぬ不具合が発見されるリスクも軽減できます。 おわりに この記事では、私が普段 PHPUnit をずっと実行している話と、その設定やメリットについて説明しました。 Mac がちょっと熱々になることがデメリットですが、今の時期は暖を取れてちょうど良いでしょう。 BASE では、テストが好きなエンジニア・アーキテクチャが好きなエンジニアが在籍していて、ローカル環境のみならず、様々な改善活動をしています。ご興味ある方お待ちしています! binc.jp *1 : 単体テストを書かない技術 #phpcon_odawara - Speaker Deck *2 : commitを積むとは「物語を書く」ことである - Speaker Deck *3 : https://x.com/t_wada/status/904916106153828352
アバター
はじめに こんにちは!Data Strategy teamでデータエンジニアをしているshota.imazekiです。 今回はBigQueryでのINFORMATION_SCHEMAを用いたBigQueryデータ監視というテーマでブログを書いていこうと思います。 BigQueryを利用していく上で「クエリが実行できなくなった」「データが古いまま更新されていない」「使われていないデータがある」などの様々な運用上の課題があるかと思います。それをINFORMATION_SCHEMAで使って簡単に解決していこうという話です。 BASEの分析基盤 まず前提としてBASEの分析基盤を簡単に紹介します。BASEではDWHにBigQueryを採用しています。BIツールとしてはLookerを導入していて、Dailyでデータが同期されるようになっています。ワークフロー管理にはAirflowを利用しており、データ連携部分にはEmbulkやS3 エクスポート機能などを使ってます。連携部分の詳細は こちら のテックブログに書いております。BigQueryはLookerから以外にもデータアナリストなどの分析者が直接クエリを実行することもあります。 BASEの分析基盤(簡略版) データ監視における課題 BASEにおけるデータ監視関連の課題は現状、以下の3点があります。 データが連携されていない、更新されないデータが連携され続けている 分析に使われていないデータが連携されている 重いクエリが実行されている 1. データが連携されていない、更新されないデータが連携され続けている データソース側やデータ連携部分で何かしらの障害が起きて、更新されるべきデータが更新されなくなっていることがあります。またこの逆で、プロダクト側での機能の廃止や外部サービスの利用停止などによって、既に更新されることのないデータを更新し続けているパターンもあります。同じデータで更新し続けている状況です。これらについてはユーザー側からの連絡や不定期の点検時に発見することが多く、対応が遅くなってしまうことが問題でした。 TABLE_STORAGE を使えば簡単にテーブル件数を確認することができます。 select distinct project_id, table_schema, -- データセット名 table_name, total_rows, -- テーブル件数 from [project_name].`region-asia-northeast1`.INFORMATION_SCHEMA.TABLE_STORAGE このテーブルを使ってDailyのデータ連携バッチ実行後などにテーブル件数を記録しておくことで、件数の変化を簡単に追うことができます。Window関数などを使って前日との件数比較を行い、同じ件数であればアラートを鳴らすということも可能になります。BASEではLookerのアラート機能を使ってSlackへ通知しています。 2. 分析に使われていないデータが連携されている BASEでは基本的にはELT形式で一度、BigQueryにデータを連携してからデータマートなどへの加工を行っています。その中には特定プロジェクトのために一時的に作られて、PJ自体は終了したがそのまま放置されているデータマートなどもあります(それによって不要になった元データもあるでしょう)。不要になったデータマートやその加工処理はコストパフォーマンスの観点から削除をした方がいいと考えていますが、こちらの発見も遅れることが多かったため、もっと早く簡単に検知できないかと考えました。 JOBS_BY_PROJECT (ORGANIZATIONなどもある), TABLES を使うことで使われてないテーブルを洗い出すことができます。 JOBYS_BY_PROJECTを使って実行されているクエリから、どのテーブルが利用されているかを見ることができます。クエリの実行履歴については一定期間以内(180日程度)までしか保持されないのでもっと遡りたい時は実行履歴を保存しておくと良いでしょう。 select j.user_email, j.query, t.project_id, t.dataset_id, t.table_id, ROUND (j.total_bytes_processed / ( 1024 * 1024 * 1024 ), 2 ) bytes_processed_in_gb, -- 処理されるGB数も分かる from [project_name].`region-asia-northeast1`.INFORMATION_SCHEMA.JOBS_BY_PROJECT j cross join unnest(j.referenced_tables) t where -- 成功したREAD文のみを取り出す j.job_type = ' QUERY ' and j.statement_type = ' SELECT ' and j.state = ' DONE ' and j.error_result is null その後、TABLESから全テーブルの一覧を取り出し、差分を見ることで使われていないテーブルを洗い出すことができます。 select distinct table_catalog, -- プロジェクト名 table_schema, -- データセット名 table_name from [project_name].`region-asia-northeast1`.INFORMATION_SCHEMA.TABLES 3. 重いクエリが実行されている 前提としてBASEでは以下のような制限をBigQueryに設定しています。 GCPプロジェクト単位でクエリ走査量の制限: Query usage per day ユーザー単位でのクエリ走査量の制限: Query usage per day per user またLookerからの1クエリ単位での走査量の制限も入れています。 これらの制限によって基本的には重いクエリが実行されてもコストが莫大に膨れ上がったり、コスト制限によって利用できなくなったといった問題は防げています。しかし、1ユーザー単位で見た時には数回重いクエリを実行しただけでBigQueryが利用できなくなってしまうこともあり、コスト的にも分析体験としても好ましくありません。 したがって重いクエリが実行された場合にそれを通知できるようにし、クエリの改善もしくはデータマートの構築などを提案できるようにしました。 2同様、 JOBS_BY_PROJECT (ORGANIZATIONなどもある)を利用することで重いクエリを洗い出すことができます。 select j.user_email, j.query, t.project_id, t.dataset_id, t.table_id, ROUND (j.total_bytes_processed / ( 1024 * 1024 * 1024 ), 2 ) bytes_processed_in_gb, -- 処理されるGB数も分かる from [project_name].`region-asia-northeast1`.INFORMATION_SCHEMA.JOBS_BY_PROJECT j cross join unnest(j.referenced_tables) t where -- 例: 100GB以上の走査量を取り出すクエリ (j.total_bytes_processed / ( 1024 * 1024 * 1024 ) > 100 Lookerのアラート機能 を用いることで、定期的に(数分単位や1時間単位など)重いクエリが実行されたかを確認し、Slackに通知することにしています。 またLookerからはサービスアカウントを用いてクエリを実行する都合上、誰か1人がLookerからQuery usage per day per userの上限に引っかかるくらい使ってしまうと他のLookerユーザーにも影響が出てしまいます。その検知も簡単に行えるようにしました。上記の JOBS_BY_PROJECT テーブルなどを日単位でtotal_bytes_processedをsumしたりすることで設定した閾値を超えた場合に通知することができるようになります。 おわりに INFORMATION_SCHEMAを用いることで分析基盤の運用がより便利になる事例を紹介してきました。正直、Data observabilityツール( elementary など)を用いた方がよりDWHの改善などには繋がると思いますが、気軽に始めるならINFORMATION_SCHEMAを使った方が良いかと考えています。BASEでもelementaryの導入などは進めていきたいとは思っていて、このような分析基盤の改善を一緒に行っていくメンバーを募集しています。ご興味のある方は気軽にご応募ください! A-1.Tech_データエンジニア / BASE株式会社 明日のBASEアドベントカレンダーはosashimiさんの記事です。お楽しみに!
アバター
この記事は BASE アドベントカレンダー 17日目の記事です。 はじめに Pay IDアプリチームの小林です。「ショッピングアプリ Pay ID」のAndroidアプリを開発しています。 今回はJetpack ComposeでConstraintLayoutを使った事例紹介をしたいと思います。 ConstraintLayoutとは まず、ConstraintLayoutとは、複雑なレイアウト、特に相対的なレイアウトを書きたいときに使うことになるクラスです。 始まりはComposeによるレイアウト作成の前、XMLにてレイアウトを書いていた頃に登場しました。 その頃はXMLだったので、複雑なレイアウトはネストして書かなければならず、分かりづらいものになっていました。 また、ネストしたレイアウトはパフォーマンス上の問題もありました。 フラットにネストなく書けるようになるConstraintLayoutは、設定のとっつきづらさはあったものの、ネストによる分かりづらさに比べたら有効なLayoutだったと感じています。 ConstraintLayoutだけで使えるレイアウト表現もありました。 その後、Composeが誕生しKotlinコードでレイアウトが書くことが可能になりました。 ネストによる分かりづらさはメソッド分け等のKotlinコードで書くことでできる手法である程度解消することができ、パフォーマンス問題もComposeはネストしても悪化しないようになりました。 注: View システムでは、大規模で複雑なレイアウトを作成する場合、 ConstraintLayout を使用することが推奨されていました。 これは、ネストされたビューよりもフラットなビュー階層の方が パフォーマンスに優れているためです。 しかし、深いレイアウト階層を効率的に扱える Compose では、 このような懸念はありません。 ( https://developer.android.com/develop/ui/compose/layouts/constraintlayout?hl=ja より転載) 前述したConstraintLayoutだけで使える表現も、RowやColumn等でも表現できるようになったりと、ConstraintLayoutを使わなければならない部分は大きく減りました。 (例: ガイドラインという表現方法の場合) 注: Rows と Columns で同様の効果を実現するには、Spacer の使用をご検討ください。 ( https://developer.android.com/develop/ui/compose/layouts/constraintlayout?hl=ja#guidelines より転載) ComposeでConstraintLayoutを使ったケース そのため、普段はComposeでConstraintLayoutを使わないのですが、Pay IDアプリで表現したいレイアウトを実現するためにConstraintLayoutを使っている箇所がいくつかあります。 1つのViewに合わせて、縦と横のラインを揃えたい場合 そのまま、ConstraintLayoutの用途である相対的なレイアウトを作りたかった場合です。 このようなレイアウトがあり、チェックアイコンの中央ラインに日付やラベルを揃えたいのとチェックアイコンの上下にある緑や灰色の棒UIも、チェックアイコンの縦真ん中に揃えたいものでした。 これらをコードに起こしてたものがこちらです。 ConstraintLayout( modifier = Modifier.fillMaxWidth(), ) { val ( topLine, checkicon, bottomLine, dateRef, // ... 他レイアウトの制約名 ) = createRefs() LowerHalfBar( // 棒の下半分 modifier = Modifier.constrainAs(topLine) { start.linkTo(checkicon.start) end.linkTo(checkicon.end) top.linkTo(parent.top) }, viewData = viewData, ) CheckBoxPaid( // チェックアイコン modifier = Modifier.constrainAs(checkicon) { start.linkTo(parent.start, margin = 16 .dp) top.linkTo(parent.top, margin = 16 .dp) bottom.linkTo(parent.bottom, margin = 16 .dp) }, viewData = viewData, ) UpperHalfBar( // 棒の上半分 modifier = Modifier.constrainAs(bottomLine) { start.linkTo(checkicon.start) end.linkTo(checkicon.end) bottom.linkTo(parent.bottom) }, viewData = viewData, ) Date( // 日付 modifier = Modifier.constrainAs(dateRef) { start.linkTo(checkicon.end, margin = 16 .dp) top.linkTo(checkicon.top) bottom.linkTo(checkicon.bottom) }, viewData = viewData, ) // ...他レイアウト } ConstraintLayout自体の書き方の説明は 公式の説明 が詳しくわかりやすいので省略しますが、各レイアウトのlinkToにチェックアイコンの上下やstart/endを設定することで、チェックアイコンに対しての中央に各レイアウトを配置することができています。 BoxやRow/Columnを使って表現しようとしたのですが、 チェックアイコン+日付等をRowで囲んで上下の棒を左寄せでアイコンの中央っぽくすると、スクリーン設定等でズレる チェックアイコン+上下の棒をColumnで囲んで、日付をそれらの中央に指定すると、微妙にアイコンの中央からはズレてしまうし、上下の棒がつながって見えない という問題があったりして、ConstraintLayoutを使うことで解決しました。 レイアウトを重ねたい場合 2つ目はUIを重ねて表現したいときです。 こちらのレイアウトなのですが の2つのレイアウトの後ろに、白背景のSpacerを重ねて表現しています。 ConstraintLayout { val (text1, image2, background3) = createRefs() Spacer( // 白背景を重ねる。先に定義する modifier = Modifier .background(Color.White) .constrainAs(background3) { top.linkTo(text1.top) // テキストと同じ高さにする bottom.linkTo(text1.bottom) // テキストと同じ高さにする start.linkTo(text1.start, 24 .dp) // テキストの少し右側から end.linkTo(image2.end, 12 .dp) // 画像の少し左側まで表示する width = Dimension.fillToConstraints height = Dimension.fillToConstraints }, ) Text( modifier = Modifier //...略 .constrainAs(text1) { top.linkTo(image2.top) //画像との中央揃えの設定 bottom.linkTo(image2.bottom) //画像との中央揃えの設定 start.linkTo(parent.start) end.linkTo(image.start) // 画像の左に配置 }, text = "最近の購入品" , ) Image( modifier = Modifier // ...略 .constrainAs(image2) { end.linkTo(parent.end) }, painter = //..., contentDescription = "画像" , ) } } このようにすることでテキストと画像の間の微妙な隙間を白背景で埋めることができます。 Spacerは何も定義しないと0dpでlinkToで幅や高さを設定しても描画されません。 そのため、width/heightでDimension.fillToConstraintsを設定することで、constrainAsで設定したそのUIが表示されていい領域いっぱいまで高さや幅を広げてくれます。 おわりに 今回はPay IDアプリでJetpack Compose上でConstraintLayoutを使っている事例を2つ紹介しました。 ここまで見ていただいた方の助けになったら幸いです。 明日は @meihei さんと shota.imazekiさんの記事が発表されます。お楽しみに!
アバター
はじめに PHPカンファレンス2024 公式ロゴより BASEのProductDev でエンジニア をしています 遠藤 です。 2024/12/22(日)の日程で開催される PHP Conference Japan 2024にてBASEは ゴールドスポンサーとして協賛します。 phpcon.php.gr.jp BASE は過去にPHP カンファレンスへの登壇並びに協賛をしております。 https://devblog.thebase.in/entry/phpcon2023-announcement https://devblog.thebase.in/entry/phpcon2022 https://devblog.thebase.in/entry/2021/10/05/110000 今年でBASEは通算8回目のスポンサーとなり、PHP コミュニティへの貢献を続けることができ大変嬉しく思います! BASEのスポンサーブースでは来場者の方に楽しんでもらえるような参加型の企画を用意しています! 企画に参加してくださった方にはオリジナルのノベルティと、BASEを実際に利用されていショップ様のコーヒーパックをご用意しております! ぜひ、BASEのスポンサーブースへお越しください! セッションの紹介について BASEで活躍されている Saki Takamachi さんがPHPカンファレンス2024にゲストスピーカーとして「PHP RMは何をする?コア開発者と兼任するメリット/裏話」というタイトルで登壇されます。 fortee.jp BASEの処理の多くはPHPで開発されており、Saki Takamachiさんを含む多くのコア開発とContributorの日々の改善により成り立っております。 そんなPHPの最新verであるPHP8.4でRelease ManagerになったSaki Takamachiさんのお話はなかなか普段聞けない話題なので、当日聞けるのがとても楽しみです! Saki Takamachさんのセッションは「トラック1 - 1F 大展示」で10:55から発表されます! ぜひ足を運んでください! おわりに 今年のPHP Conference Japan 2024の実行委員長が弊社で活躍されている @cocoeyes02 さんが担当しておりBASEで働くメンバー一同、今年の開催を心より応援しております! また、PHP Conference Japan 2024 の当日のチケットは下記よりまだお申し込みいただけます! PHPカンファレンス 2024 - connpass それでは当日、皆様にお会いできることを楽しみにしております。
アバター
本記事は BASEアドベントカレンダー2024 の16日目の記事です。 はじめに BASE FeatureDev3Group でWebアプリケーションエンジニア をしている Capi( @ysssssss98 ) です。自分は2024年の10月にBASEへ入社して今月で3ヶ月目になります。前職ではバックエンドエンジニアとしてWebAPIの開発をしたりインフラ(AWS)の管理、小規模チームの開発進捗管理やメンバー育成、オフショア開発、採用業務をしていました。 現在はBASEでプロジェクトに参画し、Webアプリケーションエンジニアとしてバックエンドだけでなく今まで実務経験がほとんどなかったフロントエンドにも挑戦しています!スクラム開発も初挑戦です! 今回は自分が新しい環境で新しい挑戦をする中で非常に効果があった開発チームでの取り組み、ペアプログラミングについて紹介します。ペアプログラミングのやり方や効果が認知され、もっとペアプログラミングが盛んになったら幸いです。 ペアプログラミングとは ペアプログラミング ( 英 : pair programming)はソフトウェア開発の手法の一つで、2人のプログラマが1台のマシンを操作してプログラミングを行う手法。 当初は、2人が1台のワークステーションに向かって作業するものだったが、現在では一人で複数台を同時に使ったり、一台に複数台のディスプレイを使うことも多くなり、具体的なやり方は変わっている。 実際にキーボードを操作してコードを書く人を「ドライバ」、もう1人を「ナビゲータ」と呼ぶ。30分ごとか、単体テストを1つ完成させる度に役割を交替するのがよいとされる。また、1日に一度の頻度でパートナーを変えるのがよいともされている。 引用: ペアプログラミング|Wikipedia ペアプログラミングは1人で実装しないところが特徴です。前職ではペアプログラミングをすることはめったになく基本1人で実装していることが多かったです。また、手を動かす人が定期的に変わるのも特徴です。複数の人間が同じことに向き合うため知識の共有や実装方法の教育によるスキル向上が見込めます。 どんな風にペアプログラミングをしているのか 次に自分のチームがどんなツールを使ってペアプログラミングを行なったのか紹介します。自分のチームが使ったツール以外でも同等の環境を準備できるので代替ツールも紹介します。 自分のチームが利用したツール 1. Gather バーチャルオフィスツールです。バーチャルオフィス内にアバターが出てきて会話する際は特定の場所にアバターが集まることで自動的にビデオ通話が開始します。画面共有やチャットもできます。 2. Figma(FigJam) オンラインデザインツールです。デザインを作るための使用が多いですが、今回私たちのチームはホワイトボートのような用途で使用しました。ペアプログラミング中のアプリケーション設計を視覚的に共有するためです。 3. Code With Me JetBrains社が提供するペアプログラミングツールです。リンクを共有すると複数のユーザーで同じコードを編集できます。どのユーザーがコードのどこを編集しているか表示できたり、ユーザーのコードを追従可能です。 代替ツール 自分たちのチームが普段使っているツール以外でもペアプログラミングをリモートで行うことは可能です。前職や過去に自分が使ったことのあるツールで今回の構成を代替できるものを紹介していきます。 1. Slack Slackのハドル機能が使えます。チャンネルに入ってるユーザーはいつでも入れますし、チャットも可能です。 2. Miro オンラインホワイトボードツールです。付箋や図形を使って視覚的に情報を共有できます。 3. Live Share Visual Studio Codeの拡張機能です。Code With Meと同様にユーザーがコードのどこを編集しているのか視覚的に確認することができます。 marketplace.visualstudio.com ペアプログラミングを通じて得られたもの 自分が持っていない実装の引き出しと技術の知識 自分が特にこのメリットを体感したのはフロントエンドの実装です。具体的にはCSSの書き方やReactのコンポーネント分割、TypeScriptによるデータフェッチ処理でした。 個人的には特にCSS実装がペアプログラミングの効果を発揮したと感じています。なぜなら自分はCSSに苦手意識を持っていたからです。タスク着手時はどうやったらデザイン通りのUIが実現できるのか、バックエンドから受け取ったデータの値によって変わる動的なUIをどこで記述するのかなど不安でいっぱいでした。 自分がドライバ(実際にコードを書く側)の時はフロントエンド経験豊富な方にナビゲータ(実装の助言を行う側)を担当していただき、どんなCSSを当てていくのかを丁寧に解説していただきながら納得感を持って手を動かしていきました。時には言葉だけでなくその場で実装を代わっていただくことでコードベースの共有をいただきました。また、自分がナビゲータの時は疑問に思ったらすぐに「なんでこのスタイルの当て方をしてるんですか?」、「このスタイルを当てると〇〇になるという認識であっていますか?」という質問を積極的に行い、経験豊富な方の思考を言語化しながら進めることができました。その中で自分の中に新しい引き出しが増えたり相手の考え方が共有されていったと考えています。 最初のフロントエンド実装タスクでは約半日ほどナビゲータの方に付きっきりで実装を見てもらっていました。しかし、2つ目のフロントエンド実装タスクでは1時間~1時間半の時間のみ見ていただくだけで他の時間は自力で実装を進められるようになりました。 個人的にはアウトプットよりインプットの方が少し多かったので今後のフロントエンド実装では自分がナビゲータになる頻度を増やし、アウトプット量の割合をより増やしていきたいです。 コードレビューの時間短縮 コードを書いてるだけでは認識を合わせるのが難しいものもあるかもしれません。自分が経験したのはバックエンドのクラス設計やクラス間でのデータの流れをペアプログラミング中のコーディングだけで伝えようとすることが難しかったです。 その時は対策としてペアプログラミング中にFigmaやMiroを使い、図解することで認識合わせを円滑に進めました。「ペアプログラミングなのだからコーディングをお互いに行う」というこだわりを持つ必要はないです。コーディングしながら別の方法で知識の共有をした方が有効な場合は別の方法を積極的に使うことも大事だと私は考えています。 心理的安全性の向上 ペアプログラミングをするとコミュニケーション頻度が増えます。実装をしながらお互いの技術知識の共有ができます。他にも休憩中に雑談をすることもあります。相互理解によってチームメンバー同士で会話することのハードルが下がります。 自分自身、最初はGatherに入ってペアプログラミングすることに躊躇してました。しかし最近は自分からGatherに入ることをチーム全体に共有できるようになったり開発メンバーがペアプログラミングしましょう!という提案を自然とできるようになりました。 また、チーム全員で開発のレトロスペクティブ(振り返り)を行った際に「ペアプログラミングを続けたい」という意見は多かったです。 ペアプログラミングの注意点 ペアプログラミングはたくさんのメリットがありますが、一方でデメリットもあります。次に自分が経験したデメリットを紹介します。 一時的にチーム全体でタスク消化に使える時間が減る ペアプログラミングは基本的に1つのタスクを2人以上で行います。つまり本来ペアプログラミングをしなければ2人で違うタスクを並行で進められるのにあえて2人で1つのタスクを対応することになります。知識の共有やメンバー間のスキル差分がなくなっていけばこのデメリットは相殺できますが、ペアプログラミング導入序盤は速度が落ちる可能性が高いです。 ペアプログラミング後の疲労 これは私が実際にペアプログラミングをして一番感じたことです。結論から言うと脳にかかる負担が大きいです。 ペアプログラミングはドライバ(実際にコードを書く側)、ナビゲータ(実装の助言を行う側)共に情報をインプットする量、アウトプットする量が多いです。コミュニケーション量が多いため相手の意見を理解する力、自分の意見を言う力、瞬発力も必要です。また、ペアプログラミング中は実装に詰まってもすぐ一緒に調べることができて解決スピードも速いです。そのスピード感からストレスフリーで実装を行うことができます。しかし、その分短期間で扱う情報量が多いです 個人的な所感として、ペアプログラミングは最長でも1時間に1回休憩を入れたほうが良いと思いました。 おわりに 以上がペアプログラミングをして自分が体験したものになります。「ペアプログラミングって聞いたことあるけどどうやったらいいんだろう?」と考えている方に何か1つでも参考になったら嬉しいです。また、新たにメンバーを受け入れる環境やメンバー全員の認識合わせを円滑にしたいチーム、メンバー同士のスキル向上を目指すチームにとってペアプログラミングの実施が有効な一手になったら嬉しいです。 BASEでは現在Webアプリケーションエンジニアを積極採用中です。興味ある方は是非ご応募ください。 採用情報 | BASE, Inc. - BASE, Inc. 明日はPay IDチームの小林さんによる記事です。お楽しみに!
アバター
この記事は BASE アドベントカレンダー 16日目の記事です。 はじめに こんにちは、CSE Group ※1 で社内の業務効率化の開発をしている上野です。 アドベントカレンダー15日目は @miyachin_87 さんの記事でした、みなさんもうお読みでしょうか?私は特に業務効率化の開発をしているので Notion での自動タスク生成の話はとても参考になりました。まだの方はぜひお読みください! devblog.thebase.in さて、アドベントカレンダー16日目の本日は、レポートシステムの安定稼働をするための取り組みについて紹介します! レポートシステムとは BASEではJ-SOX対応の一環として、 BASEショップの売上金と決済サービス側の入金データ BASEショップの売上金とBASE側の決済データ BASE側の決済データと決済サービス側の入金データ 決済サービス側の入金データと実際の入金額 これら4点の整合性が取れていることを確認することで財務報告上の信頼性を担保しています。 月初処理は月次でこれらの整合性が取れていることの確認を行うことを指しています。 (※2 より引用) この整合性を取るためのデータ収集と、各種確認のクエリ実行を行うのがレポートシステムです。 具体的には以下のような処理を行っています。 BASE の DB を日時で取得し Amazon Athena にデータを登録する 各決済システムからデータをダウンロードし、Amazon Athena にデータを登録する クエリでデータを突き合わせ、整合性が取れていることを確認する 簡単なアーキテクチャ図はこのようになります。 レポートシステムの問題点 上記の処理のうち 1. の DB のデータを Embulk で Athena に取り込む処理で、次のような課題がありました。 実行時間が長くなっていった ECS で分散処理をしていましたが、それでも午前2時に実行を開始して、午前9時過ぎまでかかることもあり、朝9時の日次レポートに処理が間に合わないことも多くなっていました。 また、何かしらで処理が詰まってしまい、翌日まで実行が完了していないなども目立ってきていました。 エラーが頻発するようになった 上記の遅延が目立つ様になってきたころから、エラーとなることが多くなっていました。(翌日までかかっても終わらず処理がバッティングする、コピーされた DB の削除処理が正常に動作できない、など) また、リカバリも再実行に 6~8 時間ほどかかってしまうため、朝にエラーに気づいて夕方にようやくデータが渡せる状況になってしまっていました。 Embulk のメンテナンスなどに工数が割けない そのため、処理速度の向上とメンテナンスコスト削減のため、マネージド・サービスを利用したETL機構に置き換え、安定稼働を目指しました。 技術選定 BASE では DB に Aurora MySQL を使用しています。 Aurora MySQL では 2022年に S3 にエクスポートする機能がリリースされていたため、これを使用することにしました。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/export-cluster-data.html https://dev.classmethod.jp/articles/aurora-cluster-export-s3/ その他、AWS Glue で Aurora のデータを出力する方法などもありそうでしたが、BASE 社内でも Data Platformチームでの利用実績 もあったことや、今までのレポートシステムが Step Functions と Lambda を SAM で管理をしており知見があったため、Lambda で Aurora S3 Export を実行する形を選定しました。 検討したこと データのエクスポートの技術を選定しましたが、具体的な方法について以下のようにな選択肢がありそれぞれ検討しました。 BASE の本番アカウントで DB を直接エクスポートする 今まで通り BASE の本番アカウントからレポートシステムにDBをコピーし、コピーされたDBからエクスポートする 1.の方法でのメリットは、2.の方法と比べるとレポートシステムのアカウントで DB を建てる必要がなくなるため、コストが削減できるという点です。対してデメリットは、レポートシステムのアカウント外での処理をワークフローに組み込む必要があることなど、複雑性が上がってしまう点でした。 2.の方法のメリットは1.の逆で、すべてレポートシステムのアカウント内で完結するため比較的複雑性が低く、CSE チーム内ですべて完結できる点で、デメリットは DB のコストでした。 しかし、2. の方法でのデメリットのコストについては、今までも同様に DB をコピーしているため大幅なコスト増加はないであろうこと、エクスポートの処理のほうが高速になるため、DB インスタンスの立ち上がっている時間の短縮ができ、結果としてある程度のコスト削減は見込めるため大きなデメリットにはならないだろうということで、2. の方法で実施することにしました。 最終的なアーキテクチャ 前述の事項を考慮した最終的なアーキテクチャは以下のようになります。 図式化する関係で簡略化しておりいくつか盛り込めていない点があるので、その点についてもいくつか紹介します。 コピーしてきた DB を一度 Snapshot を取得して、Snapshot に対して、エクスポートを実行している 原因がはっきりしていませんが、コピーしてきた DB クラスタに対して直接エクスポートをするとエラーとなってしまったため Snapshot を経由してエクスポートする処理になりました。 Snapshot からのエクスポートのため、Snapshot が完了した段階で並行処理で DB クラスタの削除処理を実行している DB インスタンスが立ち上がっている時間を極力減らしたい、処理時間を長くはしたくないということで並行して実行するようにしました。これが後述するコストにもある程度効いていそうです。 DB のコピー、Snapshot の取得、Glue crawler の実行など、ある程度時間がかかる処理は Step Functions で処理の完了を監視するような分岐を実装しました。 これらを盛り込んだ Step Functions の全体像はこのようになっています。またこれらのリソースはすべてSAMでコード化し、GitHub上で管理しています。 置き換えの効果 実行速度、安定稼働 約8時間 → 約1時間半 以前は実行時間が実質8時間以上(DB のコピーが午前1時開始、その後の Embulk の処理が2時開始のため)かかっていました。また、週に1回はエラーが出てしまう状態でした。 週に1回エラーになるので、Slackでは、そろそろエラーになると思ったらエラーだった、というやり取りもありました。 置き換え後は2時間かかることはほぼなく、エラーも置き換え直後の微調整以外なく安定して稼働できました。 コストの削減 コスト削減は前述の通りスコープ外だったのですが、実行時間が早くなったことにより Aurora のインスタンスが立ち上がっている時間が大幅に短くなったことや、Embulk での I/O がなくなったことなどの要因で RDS のコストが大幅に削減されました。エクスポートに関わる課金もあると思いますが、削減のほうが上回り、結果としてレポートシステムのアカウントでの全体コストも削減することができました。(9月以前の1年間の平均が$541、10月の途中に処理を置き換えたため10月は $114 とある程度削減され、完全に置き換えられた11月では 約$4 にまで下がっていました。1/100 以下になるとは驚きです。) RDS 単体でのコスト削減効果。脅威の 99% off アカウント全体のコスト削減効果。RDS 以外のコストには大きな変化はない事がわかる。 運用コスト削減 Step Functions と Lambda でワークフローを構築しているため、完全に運用コストがなくなったわけではありませんが、Embulk を完全に利用しなくなったことで、Embulk のバージョンアップなどを気にする必要がなくなりました。 まとめ レポートシステムのデータ取得処理を Embulk から Aurora S3 Export に変更したことで8時間かかっていた処理を1.5時間ほどまで高速化することができました。 それにより毎朝9時の通知にデータを間に合わせることができるようになり、またエラー頻度も削減でき安定的に運用できるようになりました。 また、副次的な効果として、主に RDS のコストを $500/月 から $4/月 と、99% 削減もすることができました。 おわりに 明日のBASEアドベントカレンダーは @eijenson の記事です、お楽しみに! また、BASE では Web アプリケーションエンジニアを積極採用しています。興味持っていただいたら、ぜひご応募ください! 採用情報 | BASE, Inc. - BASE, Inc. ※1 CSE チームについては少し古い記事ですが こちら をごらんください。 ※2 レポートシステムについては以前の こちら や こちら の記事もごらんください。
アバター
本記事は BASEアドベントカレンダー2024 の15日目の記事です。 はじめに Pay IDチームでプロダクトマネージャーをしているMIYACHINです。 Pay IDは、BASEで作られたショップでのお買いものを楽しむためのショッピングサービスで、クイックでスムーズな決済機能と、ショッピングアプリを提供しています。 本記事では、Notion FormとAutomation機能を活用して、定型タスクを自動生成するツールを作った話をします。 背景 新しい機能をリリースするときには、「BASE」のショップオーナーや「Pay ID」の購入者に向けて、メールやブログなどを通じて告知を行います。 BASEでは、ユーザーとのコミュニケーションの窓口を担当しているチームがあり、告知をする際は、そのチームと連携をとりながら準備を進めていく必要があります。具体的には、例えばメール配信の場合は、告知日時の調整、原稿の作成、原稿のレビュー、テスト配信などです。 しかし、開発業務に注力するあまり、これらの準備が告知日ギリギリになってしまうことがあります・・・。 一方で、これらの準備は決まりきったタスクの消化であるため、告知日から逆算して自動的にタスクを生成できれば、より計画的に準備を進められるのではないかと考えました。 また、新しいメンバーが入社した際も、これらの複雑なフローを一から覚えるのは負担が大きいため、この課題も含めて解決できる方法を模索することにしました。 検討した実現方法 Webアプリ + Notion API 開発自体は楽しそうだけど、メンテナンス可能な人材が限られることと、Notion APIキーの管理体制が未確立であることから却下。 Google Form + GAS + Notion API Webアプリより実装はシンプルだけど、GASを扱える人材が限られるため、これも却下。 Notion Form + Automation 社内のNotion相談Slackチャンネルで提案されたアイディア。Notion Formは誰でも操作可能で、Notion APIも不要であるためベストな選択肢に。 Notion Formとは? 「Notion Form」とは、Notion内でフォームを作成・管理できる機能で、2024年10月にリリースされた機能です。従来のNotionのデータベース機能に加えて、外部からの情報収集をよりスムーズに行えるようになりました。 これを活用することで、フォームの回答結果をNotionのデータベース上でリアルタイムに管理・分析できるようになります。回答データは自動的にデータベースに反映され、他のNotionページやデータベースと連携することも可能です。また、フォームのデザインも用途に応じて柔軟にカスタマイズすることができ、質問の種類や回答形式の選択、必須項目の設定など、Google Formと同等の運用をすることができます。 作り方 それでは実際にどのようにツールを作ったか、簡単にご紹介します。 1. Notion Formを作成する。 フォームには、告知日、告知媒体、告知コードを入力できるようにします。(「告知コード」が何かはこの後説明します) このフォームの回答は自動作成されるDBに入ってきます。(一旦このDBを「フォーム回答出力先DB」と呼びます。) 2. タスク出力先DBを作成する 「フォーム回答出力DB」とは別に、実際に消化していくタスクを生成する先のDBを作成します。 カラムはタスク名(タイトル)、締切(日付)、担当者(ユーザー)、ステータス(ステータス)、カテゴリ(セレクト)、メモ(文字列)、告知コード(文字列)で作成します。 3. 「フォーム回答出力先DB」にAutomationを設定する 1.で作成したフォームで選択する告知媒体ごとに”Automation”を作成します。 NotionのDBにはAutomationというものが指定でき、Automationにはトリガーと実行内容を定義できます。 トリガーと実行内容は以下のようなものが定義できます。 トリガー 実行内容 DBに新しい行が追加された時 新しい行のプロパティが〇〇だった時 特定のDBに新しい行を追加 メール / Slackで通知 Webhookを送信 このツールでは、トリガーと実行内容を以下のように設定します。 トリガー 実行内容 「フォーム回答出力先DB」の新しい行の「告知媒体」に〇〇が含まれていた場合 「生成タスク出力先DB」に特定の締切日でタスクを生成 具体的な例を挙げると、 新しい行の「告知媒体」に「メール」が含まれている場合、「タスク出力先DB」に「原稿のレビューを受ける」というタスクを告知日から3日前を締切にして作成、といった感じです。 その際に、告知日から逆算してタスクの締切日を設定しないといけないため、Notionを関数を活用して計算します。 if(day(トリガーページ.告知日.dateSubtract(5, "days")) <= 5, トリガーページ.告知日.dateSubtract(3, "days"), トリガーページ.告知日.dateSubtract(5, "days")) ※ このタスクは締切日は告知日から3日前に設定するよう計算しています。締切日が土日になる(day関数の結果が6以上)場合、締切日をさらに2日前倒しして設定しています。(変数が使えないので辛い) 上記のようなAutomationを告知媒体ごとに作成することで、フォーム回答出力先DBに行が追加されるたびに、タスク出力先DBに定型タスクが自動生成されていきます。 運用方法 タスク出力先DBに消化すべきタスクが生成されたら、このDBを各プロジェクトページから読み込みます。しかし、そのまま参照すると他の人が生成したタスクも一緒に読み込まれてしまうため、ここで使うのが最初に設定した「告知コード」です。 自分が生成したタスクには、フォームで回答した「告知コード」が紐づけられているので、その告知コードでフィルタリングして表示することで、自分に必要なタスクだけを参照することができます。 また、メールを配信するためにはどんな作業が必要か、ツールが自動生成してくれるので、新しく入ったメンバーも簡単に告知準備が進められるようになりました。 おわりに Notion FormとAutomationを使って定型タスクの自動生成する方法についてご紹介しました。 今回ご紹介したような定型タスクの消化は、どのチームでも発生するものだと思うので、参考になれば幸いです。 僕の所属しているPay IDチームではエンジニアやプロダクトマネージャー、デザイナーなど幅広い職種で積極採用中なので、Pay IDチームの話を聞いてみたい!という方はぜひカジュアル面談やX(  @miyachin_87  )などでお声がけいただけると嬉しいです! 採用情報 | BASE, Inc. - BASE, Inc. 明日はuenokaさんの記事です!
アバター