TECH PLAY

株式会社スタメン

株式会社スタメン の技術ブログ

231

こんにちは!プロダクト開発部のおしん( @38Punkd )です。 スタメンは、組織改善クラウドサービス「 TUNAG 」を提供しています。そのコア機能である『タイムライン』を、モバイルアプリでWebViewからSwiftUI / Jetpack Composeにリプレイスしました。今回は、その背景と技術選定、そして実現までの道のりをご紹介します。 リプレイスの背景 スタメンの主幹サービスである「TUNAG」は、『人と組織に働きがいを』提供することをミッションに掲げ、コミュニケーションの活性化、情報共有の促進、ビジョン浸透、人材定着、そして業務効率化をメインに、お客様の組織課題を解決するサービスです。 TUNAGにはWebアプリ版とモバイルアプリ版があり、ファーストリリースはWeb版が先行し、モバイルアプリ版もそれに追従する形でリリースされました。当時の組織のケイパビリティがWeb技術に寄っていたこともあり、モバイルアプリは、いわゆる ガワネイティブ の形式で開発を進めていました。 しかし、TUNAGをご利用いただくユーザー層が多様化するにつれて、アプリのパフォーマンス改善を求める声が次第に増えてきました。例えば、地下街のレストランや工場で働かれる方、あるいは社用端末を一律で配布され、最低限のスペックと弱い通信環境でTUNAGをご利用されているお客様も少なくありません。 私たちは、こういった方々のユーザー体験の課題を解決するため、モバイルアプリのパフォーマンス改善を真剣に検討し、技術選定の見直しを行うことになりました。 技術選定の見直し モバイルアプリ開発における様々なアプローチ方法の、一般的なメリット・デメリットを整理しました。 開発アプローチ メリット デメリット 1. SwiftUI / Jetpack Compose 高いパフォーマンスとUX: OSのUIコンポーネントを使用するため、高速でスムーズな動作。各プラットフォームのガイドラインに準拠したUI/UXを提供可。 フル機能へのアクセス: カメラやGPS等端末の全ての機能に直接アクセスでき、OSの最新機能やAPIにいち早く対応可。 開発コスト: iOS, Androidそれぞれ別の開発が必要になる。 2. Flutter / React Native 開発コスト削減: 一つのコードベースでiOS, Androidの両方に対応可。 ネイティブに近いパフォーマンスとUI: Flutterは独自のレンダリングエンジンを持ち、React NativeはOSのUIコンポーネントにブリッジするため、Swift / Kotlinに近いパフォーマンスとUI。 OS機能へのアクセス制限やライブラリ依存: 一部のOS機能には別途ブリッジ実装やサードパーティ製ライブラリへの依存が必要となる場合がある。 3. KMP / CMP (KMP/CMP)ビジネスロジックの共有による効率化: 共通のビジネスロジックをKotlinで記述し、iOS, Androidで共有可。 OSのUIの活用と柔軟性: UIは各OSのUIで実装するため、ガイドラインに準拠したUIとパフォーマンス。 (KMP)プレゼンテーション層の開発が二重になる可能性: UI層はiOS, Androidでそれぞれ開発する必要があるため、接続部分の工数は削減されない。 (CMP)成熟度とコミュニティの規模: 比較的新しい技術なため、利用可能なライブラリやツールが発展途上なことも。 4. WebView 開発コスト削減: 既存のWebコンテンツを流用でき、Web開発の知識を用いて開発可。 迅速なデプロイ: App StoreやGoogle Playの審査を通さずにコンテンツ更新可。 パフォーマンスの限界: WebコンテンツをWebView内で表示するため、複雑なUIやアニメーションでもたつきやカクつきが発生しやすい。 OS機能への制限とUXの低下: アクセスが制限されたり、ブリッジが必要な場合も。また、ストアの審査基準で単なるWebサイトの表示では却下の可能性も。 私たちの場合、 社内にSwift / Kotlinの経験者はそれぞれ複数名在籍しているが、FlutterやReact Nativeの経験者は不在だったこと クライアント側にそこまで複雑なロジックが多くないこと パフォーマンス課題が大きいため、UIの作り込みがしやすい技術が必要なこと という理由から、コア機能である『タイムライン』を、WebViewからSwiftUI / Jetpack Componseへリプレイスすることに踏み切りました。 ゴールと、その策定背景 実は、これまでもコア機能である『タイムライン』をネイティブ化しようという試みは、社内で何度か話題に上がっていました。 しかし、優先度の高い新機能開発や、モバイルエンジニアのリソース不足の問題で、残念ながら保留になってきた経緯があります。仮にネイティブ化に再チャレンジするとしても、中途半端にタイムラインのWebViewの一部コンポーネントだけをネイティブ化していては、かえって技術負債につながりかねません。 そこで私たちは、 画面単位でいち早く刷新しリリースすること を今回のプロジェクトのゴールとしました。 ゴール達成に向けた戦略 この大きな目標を達成するために、私たちは2つの戦略を立てました。 1. 社内からの共感を得る タイムラインは、20種類以上の項目の組み合わせからなる投稿の一覧が並ぶ、非常に複雑な仕様です。 そのため、エンジニアサイドのQAだけでは、不具合を発見しきれないと懸念していました。なので、より多くの人に触ってもらう社内リリースでの不具合の早期発見が重要と考えました。 エンジニアが長期間、技術刷新に時間を割くことの意味は、エンジニア同士なら理解しやすいかもしれません。しかし、エンジニアではない社員からは中々想像がつきにく、想像しにくいものに対しては興味や関心を持ってもらいにくいと考え、「そもそもネイティブ化とは何か」そして特に、「ネイティブ化したら何が嬉しいのか」の2点に絞って、全社への共有を徹底しました。そうしてプロジェクトへの理解と協力を得ることに努めました。 実際にプロジェクト開始前よりも多くの社員から、社内リリースされたアプリに対して、チャットでリアクションをもらったり、気づいたことを指摘したりしてくれるようになりました。 社内リリース期間中、不具合の修正内容を社内に報告した時の様子 2. 改善欲を抑える 技術刷新を進める中で、開発サイドから改善したい仕様やUI/UXが次々と出てくる可能性を考えました。 しかし、それら全てを都度議論していては、スケジュールが延びていく一方なので、あらかじめ改善したい仕様やUI/UXを、チームメンバーでスプレッドシートに洗い出し、デザイナーと徹底的に相談しました。 改善したい仕様やUIUX一覧 ここで洗い出されなかったものについては、議論が必要と判断された場合を除き、基本的に既存の仕様やUI/UXに合わせる方針を徹底しました。都度出てきた論点や改善点については、今回のリリース後の継続改善の一環として、改めて対応していくこととしました。 これにより、プロジェクトのスコープを明確にし、スピーディに進めることができ、プロジェクト開始から約8ヶ月でリリースを実限できました。 成果と今後の展望 パフォーマンス改善を検証するため、SwiftUI版とWebView版のタイムラインそれぞれで、大きな画像を含む全てのコンテンツが表示されるまでの速度を比較しました(下の図:縦軸はコンテンツが表示されるまでの相対値)。 その結果、通信環境が弱ければ弱い程、その差は大きくなる事がわかりました。 ネットワーク毎の速度比較 (※)『Very Bad Network』 は、iPhoneのデベロッパ用ネットワークリンク調節器にあるプリセットであり、3Gよりも弱い通信環境です。 今回の技術刷新によって、TUNAGをご利用いただく多様なお客様の環境に合わせたパフォーマンス改善を実現できました。 しかし、私たちのミッションは、パフォーマンスを改善するだけではありません。TUNAGを使ってもらうことで、『人と組織に働きがいを』最大限もたらせるようにすることが、私たちサービス開発者の本質的なミッションです。 そのためにも、今回のタイムラインのパフォーマンス改善を足がかりに、さらにプロダクト改善を進めていきたいと考えています。 スタメンではエンジニアを絶賛募集中です🙌 https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers
アバター
目まぐるしく変化するIT業界において、企業が競争力を維持し続けるためには、常に新しい知識を取り入れ、お互いに学び合う文化が不可欠です。そこで、プロダクト部門では先日、エンジニア・プロダクトマネージャー(PdM)・デザイナーが一堂に会する社内LT会を開催しました! 開催の狙い:全員で高め合う学びの場づくり 今回のLT会は、部門全体の知識共有と交流を深め、プロダクト開発における連携を強化することを目的としています。異なる職種のメンバーがそれぞれの知見を発表し、質疑応答を通じて相互理解を深めることで、個人のスキルアップはもちろんのこと、組織全体の成長に繋がることを目指しました。 今回のLT会の発表内容 今回のLT会では、多岐にわたるテーマで発表が行われました。 タイトル 登壇者 キーノート: 「アウトプットしようね」 エンジニアリングマネージャー あさしん 「ゴルフから学ぶPdMの仕事術」 プロダクトマネージャー えんまめ 「モバイルアプリ、はじめの一歩」 モバイルアプリエンジニア とんとんぼ 「Ask Devinで変わる開発スタイル」 フロントエンドエンジニア 森 「企画を動かすデザイナーの思考!『広げて絞る』アプローチ。」 プロダクトデザイナー おたけ 「Hotwireを導入しました!」 プラットフォーム部バックエンドエンジニア 近藤 「5分でのぞく!セキュリティ窓口の舞台裏」 プロダクト開発部バックエンドエンジニア じゅけい 「生成AIでどの部署でも本業に集中できるチーム作り」 Watchy事業部 エンジニア ゆんま 通常業務がある中、クオリティの高いLTばかりで、運営チームとしては感謝してもしきれません...! 今回のLT会で行った取り組みの紹介 今回のLT会では、これまでの開催で得た学びを活かし、いくつかの新しい取り組みに挑戦しました。 事前アンケートによる発表内容の決定: 開催までの時間が限られていたため、今回は事前に振り分けた各チームで事前に「他のチームに聞きたいこと」をアンケートで収集しました。これにより、短期間でも他者に価値を提供できるGiveを意識した発表が揃い、誰かが聞きたい・興味のある学びを提供できました。 各チーム代表者からの登壇者選出: 過去は立候補形式が多かったのですが、各チームから1名ずつ登壇者を決めてもらう形式を採用しました。これにより、エンジニア、PdM、デザイナーといった様々な職種の発表をバランスよく聞くことができ、幅広い知見に触れる機会となりました。 キーノートセッションの用意: 当初予定していなかったキーノートセッションですが、プロダクト部門のEM(エンジニアリングマネージャー)との雑談の中で、アウトプットへの熱い想いを聞き、発表をお願いしました。アンケート結果では、このセッションが参加者にも刺さったことが分かり、思わぬところからよい発見がありました。 ハッシュタグを作ってXに投稿する: 社内勉強会ではあるのですが、ハッシュタグを作って公開OKな範囲についてはSNSへの投稿をOKにしました。何人かご協力いただきました!少しでも社外の皆さんに当日の雰囲気が伝わればうれしいです!「 #スタメンテック 」をご覧ください! 盛り上げグッズとしてペンライトとうちわを使う: 閲覧側もなるべく参加できる形にしたかったので、質疑応答の時間を設けたり拍手をお願いしたりはもちろん、盛り上げグッズとしてみんなにペンライトや応援うちわを渡して会場を盛り上げてもらいました。まさか登壇者も人生でペンライトで応援してもらう時が来るとは思わなかったでしょう...。(ノリのいいみんなに感謝です!) オープニングの時点でぶん回してくれています🪄 #スタメンテック はじまりましたー! pic.twitter.com/Pe2IYVHdD8 — hisayuki (@hisayuki_mori) 2025年7月3日 開催した結果と今後の開催 開催後のアンケートでは、「専門外の分野を知れる機会になってとてもありがたかった」「真似してみよう、これできそうかもといったヒントになった」「どの発表も「いつか役に立つ」ではなく「今すぐ役に立つ」だったのがよかった」といった、ポジティブな感想が多数寄せられました。いただいたご意見を参考に、今後も継続的に勉強会を企画していく予定です。 今回は運営チーム3人のデザイナーとエンジニアの意志で開催していたのですが、以下のような感想もいただけて運営チームとしても開催してよかったです。 「組織のコミュニケーションを活発にし続けるのに努力と行動をしている方がいらっしゃって、良い組織が成り立つと感じました。自分もその一員になるように頑張ろうと思いました。」 さらに嬉しいことに、今回のLT会をきっかけに運営メンバー以外からも「エンジニア向けの勉強会を定期的に開催したい」という声が上がり、現在はその実現に向けて動き出しています。 私たちは、お互いが積極的に学び合い、それを発信し共有することを大切にしています。これからも、会社全体で成長し続けられるよう、学びの機会を積極的に作っていきたいと思っています。 最後に スタメンでは、Rubyエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 私たちの学び合う文化に共感し、一緒にプロダクトを創っていきたいと感じた方は、ぜひ採用情報もご覧ください! herp.careers herp.careers
アバター
こんにちは! 株式会社スタメン 、プラットフォーム部のもりしたです。 先日、7月11日(金)から12日(土)にかけて東京のTOC有明で開催された「 SRE NEXT 2025 」にオフラインで参加してきました!SRE NEXTへの参加は今回が初めてでしたが、非常に学びが多く、充実した2日間を過ごすことができました。 sre-next.dev 参加メンバー集合写真(もりしたは写真撮影係してます) なぜSRE NEXTに参加したのか? 私はSRE業務をミッションの一つとするプラットフォーム部に所属しています。日々の業務の中で「SREとして、これから何に取り組むべきか?」という問いに対し、具体的なヒントを得たいという期待を抱いていました。 今年は「 SREをはじめよう - O'Reilly Japan 」をはじめとするSRE関連書籍を多く読み込んできましたが、座学で得た知識を実際の業務でどのように実践すれば良いのか、具体的なイメージが湧かないという悩みがありました。そのため、他社事例から学ぶことが最も効果的だと考え、今回のSRE NEXTへの参加を決めました。 www.oreilly.co.jp SRE NEXT とは? SRE NEXTについてご存じない方のために、簡単にご紹介します。 SRE NEXTは、 SRE Lounge のメンバーの方々が中心となって運営・開催している、信頼性に関するプラクティスに深い関心を持つエンジニアのためのカンファレンスです。2020年に初開催されて以来、今回で5回目の開催となります。 ※ SRE : Site Reliability Engineering の略。Googleが提唱したシステム管理とサービス運用の方法論です スタメンはロゴスポンサーとしてSRE NEXTを応援! 第5回目となるSRE NEXT 2025で、なんと弊社スタメンはロゴスポンサーを務めさせていただきました!会場のTrack Aセッション会場のスクリーンでスポンサー紹介が流れていたのですが、ご覧いただけたでしょうか? ロゴスポンサー紹介。右下が弊社スタメンのロゴです 来場者数から見るSRE NEXTの熱気 閉会式で発表された情報によると、今回のSRE NEXT 2025の来場者は合計 1,272 人でした。オンラインとのハイブリッド開催でしたが、オフライン参加者が約1.4倍と多く、その内訳は以下の通りです。 合計: 1,272人 内訳: オンライン 532人 / オフライン 740人 オフライン参加者が多かったのは、やはりSpeakerや他の参加者の熱量を直接感じられたり、ブースを巡る楽しさなど、オフラインならではの魅力があったからだと感じました。 現地の雰囲気を写真でご紹介! 会場の様子を少しでも感じていただけるよう、いくつか写真を掲載します。(顔が写り込んでいる箇所はマスキングしています) SREに関するアンケートボード 会場フロアの4Fにエスカレーターで上がると、SREに関する興味深いアンケートボードがありました。 アンケートボード全体 アンケートボード左側 Q1〜Q5の回答から感じたこと: Q1(あなたのSREタイプは?): Platform Engineeringの回答が多く、現在のトレンドを反映しているように感じました。(私もプラットフォーム部なので納得です!) Q2(SLO導入レベル): まだSLOの導入が進んでいない企業が多いようですね。 Q3(SRE Practice どれが好き?): Toil削減やポストモーテムは多くの方が実践されているようです。ポストモーテムは運用が難しい側面もあるので、他社事例をさらに聞いてみたいと思いました。 Q4(あなたのSRE・エンジニア歴は?): 「 SRE サイトリライアビリティエンジニアリング - O'Reilly Japan 」が発売され、SREの存在が広く認知されてからと比較すると、10年未満のSRE歴の方が多いことがわかります。 Q5(使用している監視ツール): Datadog は弊社でも利用していますが、さらに使いこなしたいと改めて思いました。 アンケートボード右側 Q6、Q7の回答から感じたこと: Q6(SRE本読んでいる?): 「 SRE サイトリライアビリティエンジニアリング - O'Reilly Japan 」の読者数が圧倒的でした。私もかなり前に読みましたが、SREのバイブルですね。次に多い「 入門 監視 - O'Reilly Japan 」もぜひ読破したいです。 Q7(SREチームの担っている役割): SREがオンコール担当の「支援」に回ることが多いという点は興味深かったです。これは、実際に開発しているチームが主体となってオンコール対応を行い、SREがそのサポートに徹するという役割分担を示しているのかもしれません。 熱気に包まれたセッション会場 開会式前 開会式やTrack Aのセッションは広々とした会場で行われました。会場が広いため、スクリーンが2つ用意されており、どの席からも見やすい工夫がされていました。 (早い時間に着席したため、写真ではまだ参加人数は少ないです) 賑わうブース会場 ブース会場 セッションの合間には、各社のブースが並ぶ会場へ。 ガチャガチャを回せたり、美味しいコーヒーをいただけたりと、お祭り気分で楽しめました。多くの参加者で賑わっており、活気に満ちていました。 参加者の熱気が伝わる懇親会 懇親会での乾杯 閉会式後には懇親会に参加しました。 とにかく人が多く、オフライン参加者のほとんどが参加していたのではないでしょうか。 Speakerの方々は特に人気で、話を聞きたい参加者に囲まれているのが印象的でした。 特に注目したセッションとLT:SREにおけるAI活用の最前線 2日間でKeynote、セッション、LTを合わせて20近く聞きました。 全体を通して感じたのは、 AI活用 をテーマにしたセッションが多かったことです。 AIをメインテーマとしていない場合でも、内容にAIが登場する機会が多く、システム開発におけるAIの浸透を強く感じました。 今回は、AI活用に注目して特に印象に残ったセッションとLTをそれぞれ1つずつご紹介します。 SRE へのサポートケースをAIに管理させる方法 speakerdeck.com Ubie株式会社 SREのGumiさんによるセッションです。 SREチームに寄せられる問い合わせ対応による業務負担を、AIを活用して軽減した事例が紹介されました。 内製で作り込まれたAI BotやWebアプリケーションは、簡単に真似できるレベルではないと感じましたが、「こんなものを作ってみたい!」「どうやって動いているのかもっと知りたい!」と強く思いました。 特に興味深かったのは、 「AIもオンボーディングが必要」 という点です。 新しいエンジニアが入社する際と同様に、AIを立ち上げるためには、今回のケースではドキュメント整備といった準備が必要なんですね。 MCPサーバで始めたアラート整理の実験的取り組み speakerdeck.com 株式会社モニクル SREのErika TakadaさんによるLTです。 こちらもAI活用の事例ですが、 「小さいところから始められるAI活用」 という点が非常に参考になりました。 アラート通知のトリアージは経験値に大きく左右され、オンコールに加わったばかりのメンバーにとっては不安が大きい業務です。 このLTでは、MCPサーバを活用して調査のヒントとなる情報が得られるよう工夫されていました。 これにより、アラート対応の精神的な負担が大幅に軽減されるだろうと感じました。 さいごに SRE NEXT 2025に参加し、SREの最前線とAI活用の可能性を肌で感じることができました。今回の学びを日々の業務に活かし、スタメンのプラットフォームをより強固なものにしていきたいと思います。 株式会社スタメンでは、プロダクト開発に関わる全ての領域で、プロダクト職種の採用を積極的に行っています。 今回レポートしたSite Reliability Engineer (SRE)の領域にご興味をお持ちいただけたなら、ぜひプラットフォーム部にご応募ください! 皆さんとお話できることを楽しみにしています。 herp.careers herp.careers herp.careers
アバター
はじめに こんにちは、プロダクト開発部の 勝間田 です。 先日、サービスのパフォーマンス向上のため、ECSで稼働しているSidekiqコンテナのvCPUをスケールアップしました。増やしたCPUリソースを最大限に活用すべく、Sidekiqのconcurrencyも引き上げたのですが、CPU使用率が期待通りに上がらず、オートスケールが機能しないという事態に陥りました。 この出来事をきっかけに、CPU、プロセス、スレッド(concurrency)、そしてRubyのGVL(Global VM Lock)について自分の理解が不十分だと気づきましたので、これらについて調査・検証を行いました。 きっかけ:予期せぬCPU使用率の低下 私たちのサービスでは、バックグラウンドジョブの実行にSidekiqを利用しています。CPU使用率に基づいたオートスケールを設定しており、1vCPU 8GBの環境で処理していました。 ここ最近メトリクスを確認するとメモリ使用率が頻繁に100%近くに達することがあったため、安定性向上・パフォーマンス向上を目指し、コンテナのスペックを1vCPU→2vCPU、8GB → 16GBにスケールアップしました。 【当初の期待】 vCPUが2倍になったので、Sidekiqのconcurrency(同時に処理するスレッド数)も約2倍に引き上げる。 これにより、CPU使用率は以前と同水準を維持しつつ、処理スループットが2倍になるはずだった。 【実際の結果】 concurrencyを増やしたにもかかわらず、CPU使用率がスケールアップ前の半分程度に低下してしまった。 その結果、オートスケーリングの閾値にも達しない状態になってしまった。 1vCPUの時点ではCPUリソースを使い切るほどジョブを捌けていたのですが、2vCPUにしたところ増やした分のCPUが遊んでしまいました。 原因は単純で実行者であるRubyプロセスが1つのままだった点にありました。 既にご存知の方も多いかもしれませんが、Rubyには GVL という「1つのRubyプロセス内で、同時に複数のスレッドがRubyのコードを並列で実行することを防ぐ」仕組みがあります。 つまり、複数のスレッドが存在していても、実際にCPUを使ってRubyのコードを実行できるのは、常にたった1つのスレッドだけです。 参考: class Thread (Ruby 3.4 リファレンスマニュアル) そのため良かれと思ってスケールアップしたものの、結果的には手付かずの「空きCPU」を1つ作ってしまっただけでした。 concurrencyで指定した分、同時に処理されていると勘違いをしており、実際にはごく短い時間でスレッドを切り替えながら処理を進めている「見かけ上の並列処理(並行処理)」であることを理解しました。 スレッドの切り替えは以下の条件で行われます。 スレッドがCPUバウンド(処理速度がCPUの計算性能によって制限されている状態)の処理を完了させる スレッドがI/O操作を実行する(この場合自動的にGVLを解放する) GVL保持期間を超える(デフォルト100ms) 参考: スレッドの切り替え I/O待ちが発生する処理(例:データベースへのクエリ、外部API呼び出し、ファイルの読み書きなど)を行っている間は、GVLを解放する仕組みになっています。 あるスレッドがI/O待ちでブロックされると、そのスレッドはGVLを解放し、待機していた別のスレッドが実行権を得て処理を開始できます。これにより、I/Oバウンド(処理速度がInput/Outputの速度によって制限されている状態)な処理が中心のアプリケーションでは、マルチスレッドによるスループットの向上が期待できます。 コンカレンシーとパラレリズム、またGVLが行っていることをスーパーマーケットのレジに例えた解説がわかりやすかったです↓ techracho.bpsinc.jp 検証:GVLの動き 理論はわかったのですが、実際にGVLがどのように動作しているのかを確かめるため、CPUに負荷をかけるCPUバウンドなワーカーを用意して検証を行いました。 実行環境:Ruby 3.4.3 検証用ワーカー(Geminiにお願いしました) class BenchmarkWorker include Sidekiq :: Job def perform (worker_id, iterations = 50_000_000_0 ) puts " [開始] Worker #{ worker_id }" start_time = Time .now result = 1 counter = 0 while counter < iterations counter += 1 result = (result + counter + worker_id) % 1000000 # 1000万回ごとに進捗を出力 if counter % 10_000_000 == 0 progress = (counter.to_f / iterations * 100 ).round( 1 ) puts " [ #{ Time .now.strftime( ' %H:%M:%S.%3N ' ) } ] Worker #{ worker_id } : #{ progress } % " end end duration = Time .now - start_time puts " [完了] Worker #{ worker_id } : #{ duration.round( 3 ) } 秒 " return duration end end 単独でワーカーを動かしたログは以下です。 処理完了まで 約25秒 かかりました。 またputsの 間隔は約0.5秒 ほどでした。 INFO 2025-06-17T00:30:58.839Z pid=1 tid=cqx jid=bde01311593723bcb73d5bbc class=BenchmarkWorker: start [開始] Worker1 [09:31:01.059] Worker1: 2.0% (10000000/500000000) result=1 [09:31:01.552] Worker1: 4.0% (20000000/500000000) result=1 [09:31:02.089] Worker1: 6.0% (30000000/500000000) result=1 [09:31:02.606] Worker1: 8.0% (40000000/500000000) result=1 ... [09:31:24.922] Worker1: 98.0% (490000000/500000000) result=1 [09:31:25.393] Worker1: 100.0% (500000000/500000000) result=1 [完了] Worker1: 24.825秒 INFO 2025-06-17T00:31:25.401Z pid=1 tid=cqx jid=bde01311593723bcb73d5bbc class=BenchmarkWorker elapsed=26.562: done 仮説 真の並列処理の場合: 1つのワーカーを実行する時間と、2つのワーカーを同時に実行する時間は、ほぼ同じになるはず。 GVLが効いている場合: 2つのワーカーを同時に実行すると、1つのワーカーを実行する時間の約2倍の時間がかかるはず。 concurrencyが2以上のキューに対して2つ同時にエンキューしたログが以下です。 INFO 2025-06-17T00:31:32.045Z pid=1 tid=crd jid=89ef0d0e04252a9dd9dd6e12 class=BenchmarkWorker: start INFO 2025-06-17T00:31:32.045Z pid=1 tid=cpl jid=97b2acb34b6ff2c8dcf5a4fd class=BenchmarkWorker: start [開始] Worker1 [09:31:32.540] Worker1: 2.0% (10000000/500000000) result=1 [開始] Worker2 [09:31:33.200] Worker1: 4.0% (20000000/500000000) result=1 [09:31:33.932] Worker2: 2.0% (10000000/500000000) result=1 [09:31:34.103] Worker1: 6.0% (30000000/500000000) result=1 [09:31:34.980] Worker2: 4.0% (20000000/500000000) result=1 [09:31:35.104] Worker1: 8.0% (40000000/500000000) result=1 [09:31:35.929] Worker2: 6.0% (30000000/500000000) result=1 ... [09:32:19.217] Worker1: 96.0% (480000000/500000000) result=1 [09:32:19.251] Worker2: 92.0% (460000000/500000000) result=1 [09:32:20.123] Worker1: 98.0% (490000000/500000000) result=1 [09:32:20.258] Worker2: 94.0% (470000000/500000000) result=1 [09:32:21.086] Worker1: 100.0% (500000000/500000000) result=1 [完了] Worker1: 49.083秒 INFO 2025-06-17T00:32:21.159Z pid=1 tid=crd jid=89ef0d0e04252a9dd9dd6e12 class=BenchmarkWorker elapsed=49.114: done (Worker2の完了ログは割愛しますが、ほぼ同時に完了しています) ログを見ると、Worker1とWorker2の進捗が交互に出力されていることがわかります。 そして、完了までにかかった時間は 約49秒 と 単独実行のほぼ2倍 になりました。 Worker1とWorker2それぞれのputsの間隔も2倍近くの値 になっています。 2つのスレッドが同時にそれぞれ実行されているのではなく、GVLによって交互に実行されている(コンテキストスイッチを繰り返している)ことがわかりました。 続いてconcurrency: 1のSidekiqキューに対して、2つ同時にエンキューした場合の挙動についても検証しました。 INFO 2025-06-17T00:51:47.438Z pid=1 tid=cs9 jid=6f918c7413e8b90a82687d50 class=BenchmarkWorker: start [開始] Worker1 [09:51:49.372] Worker1: 2.0% (10000000/500000000) result=1 [09:51:49.867] Worker1: 4.0% (20000000/500000000) result=1 ... [09:52:14.165] Worker1: 100.0% (500000000/500000000) result=1 [完了] Worker1: 25.375秒 INFO 2025-06-17T00:52:14.174Z pid=1 tid=cs9 jid=6f918c7413e8b90a82687d50 class=BenchmarkWorker elapsed=26.737: done INFO 2025-06-17T00:52:14.176Z pid=1 tid=cs9 jid=f29879723f0eb233ea8f5c10 class=BenchmarkWorker: start [開始] Worker2 [09:52:14.663] Worker2: 2.0% (10000000/500000000) result=1 [09:52:15.146] Worker2: 4.0% (20000000/500000000) result=1 ... [09:52:38.078] Worker2: 98.0% (490000000/500000000) result=1 [09:52:38.556] Worker2: 100.0% (500000000/500000000) result=1 [完了] Worker2: 24.376秒 INFO 2025-06-17T00:52:38.556Z pid=1 tid=cs9 jid=f29879723f0eb233ea8f5c10 class=BenchmarkWorker elapsed=24.381: done ログから、Worker1が完全に終了した後にWorker2が開始されていることがわかります。 concurrencyの設定が正しく機能し、ジョブが一つずつ処理されていることが確認できました。 まとめ 今回の経験からRubyによる開発において、以下のような学びを得ることができました。 GVL(Global VM Lock)は単一のRubyプロセス内では、同時に1つのスレッドだけがCPUバウンドのコードを実行できるようにする Rubyのマルチスレッドは見かけの並列化であり、本当に並列で処理が進んでいるわけではない I/Oバウンドな処理が多い場合、I/O待ちの間にGVLが解放されるため、スレッド(concurrency)を増やすことでスループットの向上が期待できる CPUバウンドな処理をスケールさせたい場合、スレッド(concurrency)ではなくプロセスを増やす必要がある Sidekiqのconcurrencyの設定値をただ大きくするだけでは改善に繋がらない可能性がある Sidekiqのスケールアップでconcurrencyを増やした際、プロセス数自体は変わっていないため結果CPUを有効活用できないことに気づきました。この経験が、プロセス、concurrency、そしてRubyのGVLについて理解を深めるきっかけとなりました。 得た学びを生かし、効率的でパフォーマンスの高い設定を追求していきたいと思っています。 最後に スタメンでは、Rubyエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 herp.careers
アバター
はじめに こんにちは!スタメンでエンジニアをしている hisa です。 2025年5月23日・24日に東京・ベルサール神田で開催された TSKaigi 2025 に、両日現地参加してきました! 今回は、イベントの雰囲気やセッションでの学び、参加者との交流などを中心に振り返っていきたいと思います。 ちなみにスタメンは今回のTSKaigiに Goldスポンサー として協賛し、当日はブース出展も行いました! スタメンでは主力事業のTUNAGやグループ事業のWatchyで幅広くTypeScriptを活用しています。 フロントエンドのみならず、バックエンドやReactNativeでのモバイルアプリ開発など幅広い技術領域でTypeScriptによるプロダクト開発を行なっています。 こうした開発を通じて、私たちもTypeScriptコミュニティの多くの知見に支えられてきました。これからも一緒にコミュニティを盛り上げていきたいと思い、「TSKaigi 2025」に協賛させていただきました! 【スポンサーブース紹介】 @stmn_eng さんのブースです #TSKaigi #TSKaigi2025 pic.twitter.com/7kgCYAH7Qn — TSKaigi (@tskaigi) 2025年5月24日 会場の雰囲気と盛り上がり 会場となったベルサール神田には、全国からTypeScript好きなエンジニアが集まり、朝からかなりの盛り上がり。 企業スポンサーはなんと 61社 にも及び、セッション会場もブースエリアも人であふれていて、TypeScriptコミュニティの熱量を肌で感じることができました。 セッションの人気具合はすさまじく、立ち見や通路で聞く方も多く、「TypeScriptってこんなに人を集めるテーマになってるのか…!」と改めて実感しました。 朝ヨガイベントも開催しました 今回スタメンとして初めて、自社主催のサイドイベント「 朝YOGA 」をTSKaigi Day1の朝に開催しました! 会場は弊社東京オフィスにて、ヨガインストラクターの方をお招きし、カンファレンス前に体と気持ちを整える時間を提供しました。 「ヨガ未経験でもOK」「会話だけの参加もOK」という、ゆるやかなスタイルだったこともあり、朝から和やかで温かい雰囲気のイベントになりました! 改めてご参加ただいた皆様、ありがとうございました! スポンサー企業ブース巡り 会場2フロアに広がるスポンサーエリアには、 19社 のブースがずらり。 各社それぞれ工夫を凝らした企画が並び、TypeScriptの型クイズやノベルティ配布、ステッカー交換、軽食コーナーまで、終始わいわいとした雰囲気でした。 スタメンのブースでは、社内プロダクト「TUNAG(ツナグ)」の 抽選機能 を使った体験企画を実施! 来場者の方にその場で抽選にチャレンジしてもらい、当たった方にはAnker製のグッズをプレゼント🎁 また、参加者全員にオリジナルステッカーもお渡ししました! さらに今回は、TypeScriptの知識を試せる「型クイズ」や、「このコードどうレビューする?」というレビュー力を問う展示コンテンツもご用意しました。 「考えるのが楽しかった」「同僚と一緒に盛り上がれた!」といった声も多くいただき、ブース担当としてとても嬉しい時間でした。 改めて、ブースにお立ち寄りいただいた皆さま、参加いただいた皆さま、本当にありがとうございました! 📑今日の問題の答えを発表します📢 エラーが出るのは画像の部分🔍 動的に決められている型だと どのPropsにも該当しないからです✨ みなさん解けましたか👀? ご参加くださった皆さん、ありがとうございました🙌 明日も面白い問題を用意しているので挑戦してみてください🔥 #TSKaigi #TSKaigi2025 pic.twitter.com/9BYz8PJnTH — stmn, inc. Developers (@stmn_eng) 2025年5月23日 参加者交流の様子 イベント中は、セッションの合間やランチ時間、コーヒーブレイク中などに、自然と参加者同士の交流が生まれていました。 技術の話から日々の課題感、会社での開発体制まで、ゆるくも濃い会話が交わされていて、参加者の温度感の高さを実感。 個人的に印象深かったのは、Day1終了後に開催された「ダイニーさん主催のドリンクアップ」 に参加させてもらったことです。 セッションでは話しきれなかったテーマを深堀りしたり、登壇者や他社エンジニアの方とフラットに意見交換ができたりと、技術者同士のリアルなつながりを感じる時間になりました。 Day2の夜には、公式の懇親会も実施され、こちらもかなりの盛り上がり! 「来年は登壇してみたいですね」「運営やってみたい!」「チームに持ち帰って共有します!」といった声も多く聞かれ、TypeScriptという共通言語で広がるコミュニティの温かさを改めて感じました。 セッションで得られた学び 全体的に実践知の詰まったセッションが多く、ここでは特に印象に残ったテーマをいくつかピックアップして紹介します。 AI × TypeScriptの可能性 複数のセッションで触れられていたのが、 LLM(大規模言語モデル)とTypeScriptの協調 について。 例えば: 型定義を自然言語から自動生成 型に基づいたモックデータの自動作成 zod のようなスキーマベースの型をLLMで組み立てる といった例が紹介されており、「AIの出力に型で 枠 を与える」設計思想に非常に納得感がありました。 今後AIと人間の役割分担が変わっていく中で、 型がその橋渡しになる という視点は、まさにTypeScriptだからこそ生まれる展望だと感じました。 ツールチェーンの進化と型安全性の向上 TypeScript Language Service Plugin の活用例も非常に印象的でした。 ESLintでは拾えない文脈依存の型ミスを検知 型情報をもとに独自ルールで静的解析 ts-morphを使ったコードの自動生成 など、 型そのものをツールに組み込んでチームの開発体験を最適化していく取り組み が紹介されていました。 現場でもすぐ使えそうな知見が多く、特に「共通型からクライアントとAPIの両方を自動生成する」設計にはかなり興味を惹かれました! TypeScript Native Preview カンファレンス当日に発表された、 TypeScript NativeのPreview 。 これは、tscを通さずそのままTypeScriptを実行できるという話で、会場中がざわついていたトピックのひとつでした。 まだ技術的な細部はこれからのようですが、「ビルドレスなTypeScriptの未来」が示されたことは非常に刺激的で、セッション外でも話題に事欠かない内容でした。 セッション外でも学びはある イベントの中で、セッション以外の場所――廊下、ブース、懇親会、ドリンクアップ――などの何気ない会話の中にも学びのタネがたくさんありました。 「このライブラリってどうやって導入してる?」「デザイナーと型どうやって擦り合わせてる?」といった日常の悩みこそ、リアルな現場感があって、実は一番ありがたかったりします。 さいごに 2日間にわたって開催されたTSKaigi 2025は、TypeScriptを軸にした技術・人・文化が交差する、非常に濃密な時間でした。 オンラインで得る情報だけでは得られない、空気の濃さや熱量を、肌で感じられたのが一番の収穫です。 今回、スタメンはGoldスポンサーとしてブースも出展していましたが、「プロダクトを作っているチームの雰囲気」や「弊社プロダクト TUNAG の魅力」が参加者の方々に伝わったなら嬉しいです。 登壇者、運営、参加者のみなさん、そしてブースで交流してくださった方々、本当にありがとうございました! また来年、どこかでお会いできることを楽しみにしています! スタメンでは、エンジニアを絶賛募集中です🙌 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
アバター
みなさんこんにちは!はじめまして! プロダクト開発部でプロダクトマネージャーをしている 山本 です。 先日、5/19(月)にオンラインで開催されたPdMイベント「 【一人PM経験者Night】一人PMの経験に学ぶ、プロダクト&組織成長のリアル 」にて「1人PdMの立ち回りとマインド、 価値発揮するために取り組んできたこと」というタイトルで発表をしました。 私自身、社外での登壇は初めてということもあったのでテックブログでも公開してみることにしました!! 登壇した資料については X やSpeakerDeckで公開していますのでそちらもぜひみていただけたら幸いです⭐️ はじめに イベントタイトルにもある通り「1人PM経験」から当時どんなことをしてきたのか、どのようにその期間を乗り越えてきたのかなどを、「立ち回り」・「マインド」・「価値発揮」の観点から、リアルな取り組み例を交えて、新卒PdM視点でお話しました。 目次 1人PdMとして「どう価値を出すか」 1人PdMだからこその「苦労と試行錯誤」 1人PdMとしての「自分とマインドの在り方」 まとめ 01_1人PdMとして「どう価値を出すか」 PdMとしての役割が広すぎて途方に暮れそうになった時、私が意識していたのは「スピード」と「先回り」です。 特に、1人PdMの環境では、 そもそも組織やプロセスが確立されていないことが多く、開発メンバーや他部署との役割分担ができていなく、すべて自分にメンションが集中したり、逆に色々な場面でボールが落ちまくっていることが多くあると思います。 そんな環境の中で私は、1人PdMとして社内で価値発揮するために 「プロダクトを一番理解している人になり、スピード重視でアウトプットを出す」 ことを徹底してきました。 実際にどんな取り組みをしたのかというと、 「たたき」で手戻りをなくす ことと 「ステークホルダーに合わせて先回りの情報共有」 をしました。 🌟「たたき」で手戻りをなくす 仕様書(PRD)を作る前に、まず手書きのラフやカスタマージャーニーマップを描いて、関係者と「そもそも、これって何のためだっけ?」という目的のすり合わせ、5W1Hを用いてユーザーストーリーの洗い出しを徹底しました。 このひと手間で認識のズレがなくなり、その後の開発がスムーズに進みました。 結果的に、CPOとの合意形成レビューでの手戻りもほぼゼロになりました✨️ 仕様検討時に課題や構想を図解化 🌟「ステークホルダーに合わせて先回りの情報共有」 企画を進めるうえで多くの関係者がいる中で、その人たちの話し方や注目ポイントがどこかを吸収しながら、「この人には図を見せながら」「この人には要点から」と、相手に合わせて説明の仕方を変えてみました。 結果的に、相手が気にしそうなことを先回りして話せるようになるので、信頼にも繋がり、開発メンバーとの議論も建設的になりました。 02_1人PdMだからこその「苦労と試行錯誤」 1人での意思決定のプレッシャーや孤独感があり、ロールモデルや経験者がいない中で、乗り越えられたのは間違いなくチームメンバーのおかげだと思っています。 特に私自身、新卒・未経験で自分よりもプロダクト開発経験があるメンバーしかいなかった環境だったので、チームの心理的安全性を何よりも大切にしていました。 その中で、チームでの「称賛文化の醸成」と「早めの課題解決」を最優先に取り組んできました。 実際にどんな取り組みをしたのかというと、 「デイリーや振り返りでのこまめな称賛と自己アピール」 をすることと、 「エンジニアとの関係構築&自分の動きをオープン」 にしてきました。 🌟「デイリーや振り返りでのこまめな称賛と自己アピール」 チームでの振り返りをする際に、一般的なKPT(Keep, Problem, Try)に、「Thanks(感謝)」「DOYA(ドヤしたいこと)」「MOYA(モヤモヤ)」を加えています。 これにより、些細なことでも感謝を本人に伝えられる機会が増えて協力体制が作りやすくなったり、普段感じている課題感や中長期的に解決していきたい・やっていきたいことを気軽に共有できる雰囲気が生まれました。 KPTTDMという独自のやり方を構築 🌟「エンジニアとの関係構築&自分の動きをオープン」 チームが停滞している(全体的に進捗が良くない、コミュニケーションや発言が少ないなど)時は、メンバーと1on1をして、お互いの期待値やギャップ部分を話すようにしました。 さらに日常的にもコミュニケーションとることを大事にしています。 日々の朝会での雑談などを通じて、最近のトレンドの話や良かった本や記事情報などの共有をしたり、プライベートでの良かったことやニュースについてもラフに話したりしています。 期待値調整と日頃の雑談 03_1人PdMとしての「自分とマインドの在り方」 正解のないプレッシャーの中で意思決定やPJ推進をしていく必要があります。 その中でPdM自身が意思決定にブレてしまいチーム全体が不安になってしまった、PdMとしてチームをうまくリードできず、経験値のあるベテランにいつの間にかプロジェクトを先導してもらっていた。など実際にPdMとして失敗しまったことがありました。 これらの経験から、イチ開発メンバーであることをメンバーに認識してもらいながら、個人としては「はやくPdMとして安定的に立ち回れるようにすること」と「自分に少し負荷をかけ筋トレ状態つくりPDCAを回し続けること」を意識してきました。 実際にどんなことを実践してきたかというと、 「チームのイチメンバーとして、PdMとして相談しやすい人になる」 ことと 「限界を決めずに常に筋トレ状態を心がける」 ようにしてきました。 🌟「チームのイチメンバーとして、PdMとして相談しやすい人になる」 プロダクト開発においてPdMだけいても開発ができないので、エンジニアやデザイナーと一緒に開発するメンバーである意識を持つようにしています。 さらに、PdMが上に立つことが多いですが指示するだけの人ではなく、チームに頼る・頼られるの関係性を構築すること、ちゃんとPdMとしてバリュー発揮できる箇所を徹底して繰り替えることで、チームとの信頼を構築して安定的に自分自身も立ち回ることができるようになると実感しています。 頼る頼られるためにも関係構築が一番大事 🌟「限界を決めずに常に筋トレ状態を心がける」 慣れてきたりコツを掴み「安定」して動けるようになってきたら、「安定」にプラスα越えた動きを常にし続けること、 コンフォートゾーンから「ストレッチゾーン/ラーニングゾーン」にできるだけ居続けることが大事だと考えています。 常に筋トレ状態を意識して動くことで、自分の限界値が分かるようになるのと、常に自分を俯瞰してみれるようになってくるので、マルチタスクがうまくなると思っています。 04_まとめ 上記、3つの観点についてお話させていただきました。 私自身は1人PdM期間としては約1年ほどでしたが、1人体制は大変な環境ではあると思います😂 ですが、個人的には一番成長実感があり「自由と責任」の中で色々PDCAを回せた貴重な期間だったと感じています。 自分が止まると開発側が動けないのではないか?などプレッシャーを感じることもありますが、ちゃんとPdMとしてメンバーとしてどうすべきかを考えて動くことで、チームとの信頼も築け同じ先を向いてプロダクトづくりができると思っています。 また、スタメンではチャレンジや成長できる環境があるだけでなく、周りにはサポートしてくれたり一緒に頑張ってくれる仲間も沢山いるので、未経験且つ1人PdMの私でも複数のPJを担当しリリース〜改善まで担当ことができました🌟 この記事が、同じ1人PdM経験者の方・経験中の方にも共感していただけたり、新卒PdM・未経験PdM・PdMを目指している方にも参考になれば嬉しいです🌟 SpeakerDeckはこちら▼ speakerdeck.com 最後に! スタメンでは一緒に働く仲間を募集しております!! ポジションは絞らず、プロダクト職全方位で採用してますので、ぜひご興味ある方いましたら採用サイト宛にご連絡ください⭐️ お待ちしております!!! recruit.stmn.co.jp 〜最後まで読んでいただきありがとうございました🌷〜
アバター
はじめに はじめまして! 2025年2月より、株式会社スタメンにプロダクトマネージャー(PdM)としてジョインしました、えんまめです。弊社ではあだ名文化があり「えんまめ」と呼ばれています。 私は以前Webエンジニアとしてキャリアをスタートしました。そこからPdMという新たな役割に挑戦し、そしてこのたび、「エンゲージメント経営プラットフォーム『TUNAG』」などを提供する株式会社スタメンの一員となりました。 「なぜWebエンジニアからPdMへ?」「そして、なぜスタメンを選んだのか?」 このエントリは、そんな私のキャリアの転機やスタメンへの入社理由を語るものですが、それだけではありません。 「スタメンってどんな会社?」 と興味を持ってくださった方 「他の人は転職で会社を決めるとき、何を考えているんだろう?」 と気になる方 「キャリアチェンジって実際どうなの?」 と考えている方 など、職種や立場に関わらず、多くの方に読んでいただけると嬉しいです。 このエントリでは、私のこれまでの道のりや、スタメンという会社に感じた魅力、そしてこれからここで何を成し遂げたいのか、その「なぜ?」の部分を少し詳しくお話しできればと思っています。 転職のきっかけ 前職では、実名口コミのグルメサイト「Retty」を運営するRetty株式会社に約9年間、Webエンジニアとして勤務していました。 Rettyでは、サービスの成長と共に個人としても多くの貴重な経験をさせていただき、特に会社の上場という大きな節目に立ち会えたことは、私にとって非常に有意義な期間でした。開発業務を通じてユーザーに価値を届けることの喜びを感じながら、充実した日々を送っていました。 そんな中、気がつけば勤続9年。40歳という年齢が目前に迫ってきたとき、ふと「この先の自分のキャリアをどう描いていこうか」と深く考えるようになりました。これまでの経験を土台に、新しい挑戦をすることで、さらに自分自身を成長させたい。その想いが次第に強くなり、長年お世話になったRettyを退職し、新たな環境である株式会社スタメンへの転職を決意しました。 転職時に何を軸としていたか 新たなキャリアを考えるにあたり、私はいくつかの譲れない軸を持って転職活動に臨みました。これまでの経験を踏まえ、これからの自分が最も輝ける場所はどこか、真剣に考えた結果、以下の3つのポイントを特に重視していました。 1. 「誰と働くか」――共に働くイメージを描けるか まず最も大切だと感じたのは、「誰と働くか」ということです。私自身、面接を受けさせていただく立場でありながら、過去には面接を担当した経験もあります。その経験から、面接の場でお会いする方々に対して「この方たちとこれから一緒に働く姿を具体的にイメージできるか」「同じ目標に向かって、気持ちよく連携しながら仕事を進められそうか」という点を、自分の中で非常に重要な判断基準として持っていました。互いに尊敬し合い、切磋琢磨できる仲間がいる環境を求めていました。 2. 「自身の強みを活かせるか」――経験を糧に、新たな価値を創出 次に、Webエンジニアとしての長年の経験や、そこから培ってきた課題解決能力、そしてPdMとして新たに挑戦したいという想い、これら「自身の強み」を最大限に活かせる環境であることも重要な軸でした。単にスキルを発揮するだけでなく、その強みをもって事業やプロダクトの成長にダイレクトに貢献できる実感を得たいと考えていました。 3. 「会社の文化やコミュニケーション」――職種を超えた活発な連携 最後に、会社の文化やコミュニケーションのあり方も重視しました。特に、エンジニア、デザイナー、ビジネスサイドといった職種の垣根を越えて、日頃からコミュニケーションが活発に行われているかという点は非常に気にしていました。それぞれの専門性を尊重しつつ、プロダクトという共通の目標に向かって誰もがオープンに意見を交わし、建設的な議論ができる。そういった風通しの良い環境こそが、一体感を醸成し、より良いプロダクトを生み出す原動力になると考えていました。 これらの軸を満たす企業で働くことこそが、自分自身の働きやすさはもちろん、PdMとしてのさらなる成長にも繋がると信じていました。 スタメンに決めた理由 私が転職活動で大切にしていた3つの軸。それらが株式会社スタメンとどのように合致し、最終的に入社を決意するに至ったのかをお話しします。 1. 「誰と働くか」――鮮明に描けた「共に働く未来」と、温かい歓迎の心 転職軸の筆頭に挙げていた「誰と働くか」。これについては、スタメンの選考プロセスを通して、他社とは比較にならないほど鮮明に「この人たちと一緒に働きたい」というイメージを抱くことができました。 面接でお会いした方々とは、私が面接官の経験も踏まえて重視していた「共に働く姿を具体的にイメージできるか」という点で、最もポジティブな感触を得られました。さらにスタメンでは、選考の過程で、これから一緒に働くことになるであろうメンバーとの座談会を必ず設けてくださったのです。そこでは、実際の業務の進め方やチームの雰囲気など、より踏み込んだ質問をすることができ、入社前に気になる点を丁寧に解消してくれました。 そして何よりも心を動かされたのが、選考の最後に、面接や座談会でお会いした方々全員から心のこもったお手紙をいただいたことです。一人ひとりからの温かいメッセージは、私という個人をしっかりと見てくれているという実感と共に、「ぜひこの仲間たちと働きたい」という気持ちを決定的なものにしてくれました。 2. 「自身の強みを活かせるか」――技術的背景を持つPdMへの期待 次に重視していた「自身の強みを活かせるか」という点です。PdMとしてのキャリアはまだ浅い私にとって、長年培ってきたWebエンジニアとしての経験や技術的な知見を、新しい役割でどのように活かせるかは非常に重要なポイントでした。 面接では、その点を率直にお伝えし、現時点で自分にできること、そしてこれから伸ばしていきたいスキルについて包み隠さずお話ししました。すると、スタメン側もちょうど「技術的なバックグラウンドを理解し、エンジニアとよりスムーズに連携できる、いわゆる『Tech寄りのPdM』」を求めているタイミングだったのです。私のこれまでの経験と、スタメンがプロダクト開発を加速させる上で必要としていた人物像が、まさに合致した瞬間でした。 この出会いにより、「ここならば、私の強みを最大限に活かし、自身の成長につなげられる」と強く確信することができました。 3. 「会社の文化やコミュニケーション」――エンゲージメントを体現する、健全で活発な風土 そして最後の軸が、「会社の文化やコミュニケーション」です。スタメンは、「エンゲージメント経営プラットフォーム『TUNAG』」をはじめとするサービスを通じて、組織のエンゲージメント向上を支援している企業です。その事業内容からも想像できるように、自社内でも称賛の制度が運用されていたり、職種を超えたコミュニケーションが非常に良好であると感じました。 (個人的には、ゴルフ部があるという点も、実はかなり大きな魅力でした!) 特に印象的だったのは、座談会などを通じて感じた「言うべきことは、お互いの成長のために率直に伝える。だけど、日常の小さな頑張りや成果も見逃さずに称賛しあう」という文化です。これはまさに、私が理想としていたオープンで建設的、かつ温かいコミュニケーションが根付いている証だと感じました。このような健全で活発な風土こそが、心理的安全性を高め、チーム全体のパフォーマンスを向上させるのだと改めて確信しました。 これら3つの軸が、スタメンという会社と見事に合致したことで、私は迷いなく入社を決意することができました。 実際スタメンに入ってみて さて、いよいよ実際に入社してからの話をさせていただきます。 正直なところ、スタメンで7社目と、私自身かなり多くの会社を経験してきました。そのため、どんな会社であれ、入社前と入社後で何かしらのギャップが生じるのはある意味当然のことだと、ある種の覚悟を持っていました。 しかし、スタメンは良い意味でその「前提」を裏切ってくれました。これまでお話ししてきた「誰と働くか」「自身の強みを活かせるか」「会社の文化やコミュニケーション」といった軸の部分で、大きなギャップを感じることはほとんどありませんでした。驚いたことに、入社初日から本当にたくさんの社員の方々と自然にコミュニケーションを取ることができ、温かく迎え入れてもらえていることを実感しました。 また、スタメンは名古屋にも本社があり、私は東京本社所属なのですが、同じ部署の名古屋メンバーともオンラインですぐに顔を合わせ、話す機会を積極的に作ってくれました。物理的な距離はあっても、チームとしての一体感やメンバー同士の繋がりを強く感じることができ、「離れていても近い存在」だと思えています。 何より、「この規模の会社で、これほど全員が同じ方向を向き、同じ熱量でプロダクトや事業に取り組んでいるのか」という事実は、私にとって最大のポジティブな驚きでした。面接や座談会で感じた一体感は本物で、それが日々の業務の中でも随所に現れているのです。 入社前に抱いていた期待は、良い意味で裏切られ、今はスタメンの一員として働けることに大きな喜びと手応えを感じています。 さいごに 以上が、元Webエンジニアである私が、PdMとして株式会社スタメンに入社を決めた理由や、実際に入ってみての率直な感想です。 スタメンの一員として、私たちは自分たち自身が前向きに楽しく働くことはもちろん、主力プロダクトである「エンゲージメント経営プラットフォーム『TUNAG』」を通じて、TUNAGを利用してくださる多くの企業の皆様、そしてそこで働く従業員の皆様にも「働くって楽しい!」「この会社で良かった!」と感じていただけるような、そんな世界を実現したいと本気で思っています。 もしこのエントリを読んで、少しでもスタメンや私たちの取り組み、あるいはPdMという仕事に興味を持っていただけたなら、ぜひカジュアルにお話ししませんか? 最後までお読みいただき、本当にありがとうございました! herp.careers herp.careers
アバター
この度、株式会社スタメンは、TSKaigi 2025にGoldスポンサーとして協賛します。 スタメンでは、企業や組織の業務DX・エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG 」を開発・提供しています。TUNAGでは、フロントエンド開発にTypeScriptを活用しています。 また、グループ事業として展開している、クラウド型のIT資産管理・操作ログ管理サービス「 Watchy 」では、フロントエンド・バックエンドともにTypeScriptを積極的に活用しています。 私たちの事業と開発組織が成長できたのは TypeScriptコミュニティの支えがあってこそであり、今後のさらなるコミュニティの発展に貢献するため「TSKaigi 2025」へ協賛いたします。 本カンファレンスへの協賛を通して、これからのTypeScriptコミュニティの発展を後押しし、イベントを一緒に盛り上げていきます! TSKaigi 2025 開催概要 名称 TSKaigi 2025 開催日時 2025年5月23日(金)〜24日(土) 場所 ベルサール神田(東京都千代田区) 詳細については、下記公式サイトをご覧ください 👇 2025.tskaigi.org ブース出展について スタメンブースでは、「TUNAG」の実際の機能を活用した参加型イベントを実施します! 来場者の皆さまに楽しんでいただけるよう、抽選イベントやプレゼント企画などをご用意しています。 抽選イベント 別カンファレンスでもご好評いただいた抽選イベントを、TSKaigiでも実施します! プロダクト「TUNAG」の一部機能を体験しながらご参加いただける仕掛けとなっており、参加いただいた方には、参加賞やちょっと嬉しい景品もご用意しています(※数に限りがございます)。 TypeScriptコードレビュー&クイズ 弊社エンジニアが用意したTypeScriptをテーマにした “考えるお題” をいくつかご用意しています。 「我こそは!」という皆さまの挑戦をお待ちしています! 当日ブースで出す予定のコードレビューのお題を、少しだけ先出しします! // このコードあなたはどうレビューしますか?? interface Item { id : number ; data : any ; } const processItem = ( item : Item ) => { console .log( `Processing item with ID: ${ item. id} ` ); if ( typeof item.data === 'string' ) { console .log( `Data (string): ${ item.data. toUpperCase () } ` ); } else if ( typeof item.data === 'number' ) { console .log( `Data (number): ${ item.data * 2 } ` ); } else if ( Array . isArray (item.data)) { console .log( `Data (array): ${ item.data. length} elements` ); } else { console .log( `Data (other): ${ JSON . stringify (item.data) } ` ); } } ; // ...続きはお楽しみに! // TypeScriptに慣れている方なら、気になるポイントがいくつかあるかもしれません...。 // ぜひ当日ブースでお話ししましょう! 他にもTypeScriptにまつわるクイズをご用意しています! 皆さまのお越しを心よりお待ちしています! おわりに 最後まで読んでいただきありがとうございます。 弊社からはエンジニア、HR含め7名が現地参加します! ブースやイベント等でお話できることを楽しみにしています! 当日会場ではどうぞよろしくお願いいたします。 サブイベントのご案内 stmn.connpass.com stmn.connpass.com スタメンではTypeScript コミュニティが好きなエンジニアを絶賛募集中です。 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
アバター
はじめに こんにちは、プラットフォーム部の 近藤 です。 2025年4月9日〜11日にアメリカ・ラスベガスで開催された「Google Cloud Next 2025」 *1 に、私とCTOの野口の2名で現地参加してきました。 Google AI Studio を用いて周囲の人物を消したところ顔が歪んでしまいました 会社全体での Google Workspace の利用や、前回の記事で取り上げた Google Kubernetes Engine (GKE) など、その他にも様々に弊社では Google Cloud を活用しています。 tech.stmn.co.jp 弊社の海外イベントへの参加は、2019年の AWS re:Invent 以来です。 tech.stmn.co.jp Looking Back on Next '25 and Its Theme 2025年の振り返りにあたり、過去のイベントも改めて整理してみます。 コロナ禍を経て久しぶりのオンサイト開催となった Next’23 は、Google Cloud が 生成AI へ本格的に参入する姿勢を明確に示した年でした。Google Cloud は、Duet AI をGoogle WorkspaceとGoogle Cloud Platform 全体に導入する方針を発表しました *2 。この時期はちょうど OpenAI の ChatGPT が大きな話題となっていた頃でもあります。 続く Next’24 では、Duet AI は Gemini へとリブランディングされ、発表されました。Gemini Code Assist や Gemini Cloud Assist といった、各分野の専門的なタスクを支援するAIアシスタント群が登場し、汎用的なAIアシスタンスからより特化した機能への流れが見られました。これにより、AI は単なる受動的な情報提供に留まらず、能動的なタスク実行へと進化する可能性が示されました *3 。 これまでの流れを踏まえて Next'25 を振り返ると、AIエージェント時代 の本格的な幕開けと、Google Cloud がその実現に必要な技術スタック全体を構築するという明確な戦略が打ち出されたイベントでした。特に、Agent Development Kit (ADK) やオープンな Agent2Agent (A2A) プロトコルの発表は、マルチエージェントエコシステムという新たなAIの枠組みを示唆するものでした *4 。まさに、汎用的な生成AIから、より高度なAIエージェント、そしてマルチエージェントエコシステムへと時代が進んでいく方向性が、鮮明に示されています。 最高の席で Keynote を観ました The full stack of AI Innovation Keynote でエージェントが強く打ち出されていたことは、エキスポエリアの活況からも如実に感じ取ることができました。多くのパートナー企業が、それぞれのデモを積極的に展示・紹介していました。デモの多くは、AIワークフローと呼ばれるものかもしれませんが、ともあれAIエージェント時代への移行期にあることを肌で感じられる場でした。 GitLab のブースでマグカップと靴下をいただきました その中で Google Cloud は、この新たな AI エージェント時代を本格的に推進するため、AI ハイパーコンピュータ、高性能な基盤モデル、エージェント開発・実行環境、そして多様なエージェントそのものに至るまで、エンドツーエンドの技術スタックを網羅する統合的なプラットフォームプレイヤーを目指す戦略を明確に示しました。 Google Cloud Next 2025 サマリーセッション (日本語) より 具体的には、AIワークロードを支える AI ハイパーコンピュータとして、第7世代TPUである Ironwood が紹介されました。また、エージェントの基盤モデルとしては、高い性能を持つ Gemini 2.5 の発表がありました。さらに、エージェントの開発、管理を効率化するための Vertex AI の大幅な機能強化 や、Google Agentspace のようなエージェント関連の具体的な取り組みも紹介され、エージェント構築のための包括的な環境が整いつつあることが示されました。 Multi-Agent Ecosystem イベント参加当時まで、AIエージェントをまだ先の未来の話だと捉え傍観していた私にとって、Next'25 のセッションやエキスポエリアで目にした発表の数々は、驚きと同時に焦りを感じさせるものでした。そして、Google Cloud が提唱した Agent2Agent (A2A) *5 に基づくマルチエージェントエコシステムという新たな枠組みには、特に大きな衝撃を受けました。 ところで、2024年11月に Anthropic が公開した Model Context Protocol (MCP) の注目が、現在高まっています *6 。MCP は、AI アシスタントが外部のデータソースやシステムと連携するためのプロトコルとして提案されています。MCP が AI とツール間の連携を目的とするプロトコルであるのに対し、A2A はエージェント同士がセキュアに相互に連携するためのプロトコルという点が異なります。A2A は単体のエージェントの能力拡張を目指す MCP を補完し *7 、エージェント間の協調によるエコシステムを実現する可能性を秘めています。 こうしたエージェント間の連携が進めば、各エージェントは特定の役割や専門領域に特化(バーティカル化)していく方向に進むと個人的には想像しています。MCPに関してはセキュリティ上の懸念も指摘される中、A2A がセキュアなプロトコルを目指している点も、印象深く感じられました。 Announcing the Agent2Agent Protocol (A2A) より これらの新たなプロトコルが、今後スタンダードな地位を確立できるかは現時点では不透明です。しかし、紛れもないリーディングカンパニーである Google がこれを主導する姿勢を見せたことには、個人的にも大きな期待を寄せざるを得ません。A2A の発表パートナーリストには Anthropic の名前が見当たらなかった点は気になります。MCP を主導する Anthropic が A2A に対して今後どのような見解や動きを見せるのか、引き続き注目していきたいポイントです。一方で、Google が Anthropic へ追加投資を行ったことも記憶に新しく *8 、両社の良好な関係が維持されることを期待しています。 The Innovation of GKE せっかくなので、セッションについても簡単に取り上げさせてください。イベント全体の話題の中心は AI でしたが、個人的には Google Kubernetes Engine (GKE) のアップデートに関するセッションにも注目していました。特に、「GKE turns 10 and looks to the future of Kubernetes」というセッションでは、GKE の10周年を記念しつつ、次世代の GKE イノベーションについて具体的に紹介されていました。 本セッションでまず強調されていたのは、Google Cloud が大規模クラスタのスケーラビリティに重点的に投資している点です。具体的に 65,000ノード規模のクラスタをサポートするという話は、大規模なエンタープライズ顧客や、複雑かつリソース消費の多い AI ワークロードを GKE 上で実現していくことの、明確な意思表示と言えるでしょう。 そうした発表の中でも、私が個人的に思わず声をあげそうになったアップデートが、In-Place Pod Resizing です。Kubernetes v1.27 でアルファ機能として導入された、コンテナを再起動することなくポッドに割り当てられた CPU/メモリリソースのサイズを変更できる機能です *9 。Kubernetes v1.33 では、ベータ版に移行されました *10 。現在、弊社で稼働している GKEクラスターでは Vertical Pod Autoscaler (VPA) を利用したポッドのリソース調整も行っていますが、再起動が発生するという点がまさに運用上の課題となっていました。この In-Place Pod Resizing 機能が、GKE Autopilot 1.33 以降でアルファ/ベータとして利用可能になる見込みとのことで、非常に期待できるアップデートです。 Del Taco の BURRITOS がお気に入りでした おわりに 今回の Google Cloud Next には、業務の一環として参加させていただき、会社に宿泊費と交通費を負担していただきました。不在中に業務をサポートしてくれたメンバーにも、この場を借りて改めて感謝を申し上げます。 イベントでの様々な発表やデモに触れる中で、私自身の AI 利用がまだ限定的であること、そしてもっと積極的に、高い解像度で活用を進めていく必要があることを強く実感しました。特に、2025年1月からは Google Workspace 全プランに AI が標準搭載されており、まずは身近なツールから積極的な活用を図っていきたいと考えています。 また、イベントを通じて AI エージェント時代におけるプロダクトマネジメントのあり方にも、個人的な関心が大きく高まりました。AI が業務を劇的に効率化する可能性は明らかであり、プロダクトの提供側としては、この強力な AI をいかにプロダクトに組み込み、ユーザーに新たな価値として届けていくか、が今後ますます重要になってくると予想されます。ひとりの技術者としても、AI の理解を深め、そのポテンシャルを最大限に引き出し、社会に貢献できる形で価値を提供していく責務があると感じています。 弊社では、エンジニア採用を積極的に行っています。少しでも興味を持っていただけたら、ぜひまずはカジュアル面談でお話しできればと思います。 herp.careers *1 : https://cloud.withgoogle.com/next/25 *2 : https://cloud.google.com/blog/topics/google-cloud-next/next-2023-wrap-up?hl=en *3 : https://cloud.google.com/blog/topics/google-cloud-next/google-cloud-next-2024-wrap-up?hl=en *4 : https://cloud.google.com/blog/topics/google-cloud-next/google-cloud-next-2025-wrap-up?hl=en *5 : https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/ *6 : https://www.anthropic.com/news/model-context-protocol *7 : https://google.github.io/A2A/#/topics/a2a_and_mcp.md *8 : https://www.nytimes.com/2025/03/11/technology/google-investment-anthropic.html *9 : https://kubernetes.io/blog/2023/05/12/in-place-pod-resize-alpha/ *10 : https://kubernetes.io/blog/2025/04/23/kubernetes-v1-33-release/#beta-in-place-resource-resize-for-vertical-scaling-of-pods
アバター
はじめに こんにちは、プロダクト開発部の 勝間田 です! もうすぐGWですね!まとまった時間が取れるこの機会に、読書をしようと考えている方も多いのではないでしょうか。 今回は私含め、スタメンエンジニアが最近のお気に入り書籍を紹介させていただきます! 技術書・ビジネス書などジャンルは問わず、良かった本を自由に挙げてもらいました。 この記事で気になる・読んでみたいと思うような本が見つかれば幸いです。 におうコードの問題集 〜MySQLインデックスに立ち向かう編〜 最初は勝間田が紹介します!普段はTUNAGのバックエンドを担当しています。 私が紹介する本は『におうコードの問題集 〜MySQLインデックスに立ち向かう編〜』です。 におうコードの問題集 〜MySQLインデックスに立ち向かう編〜 私自身「インデックスについてなんとなくわかる...」、「EXPLAINの結果を見て、効いているか効いてないかぐらいは...」というような状況でした。 そのためEXPLAINの見方がわかりやすく解説されている書籍を探していたところ、この書籍に出会いました! MySQLのインデックスが「そもそもどういう仕組みで動いているのか?」という基本的な部分から「なぜインデックスが効かなくなることがあるのか?」、「EXPLAINの結果で注目すべきポイント」まで丁寧に解説されています。 内容が具体的であり、キャラクターによる対話形式のため楽しく話が入ってきました。 EXPLAINの見方についての解説がわかりやすかったのがおすすめポイントです。 この書籍のおかげで、実務でのEXPLAINの活用イメージが明確になった気がします。 ページ数も約110ページと短いので、連休で一気に読み切れる量かなと思います! 以下のような方に特におすすめだと感じました!当てはまっている方はぜひ読んでみてください! MySQLのインデックスについて基礎からしっかり理解したい方 EXPLAIN の結果をなんとなくしか見れていない、読み解き方をちゃんと知りたい方 パフォーマンスを意識して、より適切なインデックスを設計・利用したい方 難しい技術書は挫折しがちだけど、対話形式なら読みやすいかも、という方 WHYから始めよ! インスパイア型リーダーはここが違う おしん( @38Punkd )です。 TUNAG iOS の開発を主に担当しています。 僕が紹介する本は 『WHYから始めよ! インスパイア型リーダーはここが違う』です。 WHYから始めよ! インスパイア型リーダーはここが違う 作者: サイモン・シネック 日本経済新聞出版 Amazon 大学で学生団体の活動をしていた頃に、理想のリーダー像がわからず悩んでいたことがきっかけで出会った本です。 WHY, HOW, WHATの3つの円から成るゴールデンサークルで有名な、『人を動かすのは “何をやるか” ではなく “なぜやるか” 』がキーメッセージの本です。 チームや組織を動かすためのリーダーシップのあり方や、“モノ売り“から脱却して感情で動くストーリーを語る重要性について学べました。 コードを書くのは勿論エンジニアの仕事の一つですが、この本が勧める「WHYから始める」考え方で仕事をすることで、ビジネスマンとしての成長にも繋がると思っています。 新規プロジェクトをこれから担当するけどチームを引っ張るのが不安に感じる方に特におすすめします。 プロを目指す人Ruby入門 スタメンのじゅけいです。 自分はTUNAGのバックエンド開発を担当しています。 僕が紹介する本は プロを目指す人のためのRuby入門 です。 自分はこれまでRubyに触れたことがなくスタメンに入って初めて触ることになりました。そこでおすすめいただいた本が本書になります。 プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ) 作者: 伊藤 淳一 技術評論社 Amazon 本書のコンセプトは第1章のイントロダクションでも語られている通り、Ruby開発で必要なナレッジの網羅的な解説になります。 良さを語り尽くすには語彙も時間も文章力も足りないので、自分がためになったと感じるナレッジを一部抜粋します。 Rubyではnilもtrue/falseも全てオブジェクトで振る舞いを持つ p、pp、puts、printの違い moduleのmix-in nilすらオブジェクト扱いでメソッドを持つというのは新鮮です。 また、プリントデバッグの際は内部仕様的にデバッグ用途ならpの方が好ましいというのは細かいけれど重要な違いだと感じました。(ちなみにppは配列などを渡すと展開して出力してくれるので便利) moduleの仕組みについては、継承などの他共通化アプローチとの使い分けの整理が不十分ではありますが、自分の中でのクラス設計の幅が広がりました。 Rubyは改めて記法が多彩で自由な言語だと感じました。細かな仕様を網羅的かつ丁寧に解説してくれる本書は、Rubyに初めて触れる方にぴったりの一冊だと思います。ぜひ読んでみてください。 実践Vim 思考のスピードで編集しよう! とんとんぼ です。今年(2025年)4月より TUNAG の iOS エンジニアとしてスタメンにジョインしました! 私が今回ご紹介したいのは、多くの Vimmer にはおそらくお馴染みの名著『実践Vim 思考のスピードで編集しよう!』です。 実践Vim 思考のスピードで編集しよう! (アスキー書籍) 作者: Drew Neil , 新丈 径 角川アスキー総合研究所 Amazon 私自身、プログラミングを始めたばかりの頃に、キーボードとマウスの間を頻繁に行き来することに煩わしさを感じ、「この問題をどうにか解決したい」と考えていた際、本書の『思考のスピードで編集しよう!』というキャッチーなタイトルに強く惹かれて手に取りました。 本書の大きな特徴は、現場でよく遭遇するであろう具体的な問題をTips形式で121個も取り上げ、その解決策を解説している点にあり、非常に実践的な内容となっています。中でも特に印象に残っているのは、Vim特有のモード(Normal, Insert, Visual)の概念を画家になぞらえて説明している箇所で、この本を通じてVimを習得すれば、まるで絵画を描くようにコーディングを進められ、プログラミングがより一層楽しくなるだろうと感じさせてくれます。 私自身は開発プラットフォームの事情で主にXcodeを使用していますが、本書の影響もあり、Vimのキーバインドモードを設定してVimライクな操作で開発を進めています。幸いなことに、本家であるvi、Vim、Neovimはもちろん、VSCode、Zed、さらには競合とされるEmacsでさえ拡張プラグイン(Evil)を使えばVimのキーバインドを利用できるため、本書で得たスキルは様々なエディタ環境で応用可能です。 Emacs で Vim 操作する図(Evil) 最後に いかがでしたでしょうか。 今回は、4名のメンバーがそれぞれの視点でおすすめする書籍をご紹介しました。 技術的な学びを深める本、新しい視点を与えてくれる本など、様々なジャンルの書籍が集まったのではないでしょうか。 気になる一冊が見つかった方は、この長期休みの機会にぜひ手に取って読んでみてください! 最後までお読みいただき、ありがとうございました!! 採用情報 スタメンでは、全技術領域でプロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers
アバター
皆さん、こんにちは。 株式会社スタメン CTO室の根岸です。 今年の4月に 新卒未経験エンジニア としてスタメンに入社しました! どうぞよろしくお願いいたします☺️ 本日は、 RubyKaigi 2025 のレポートをお届けします! スタメンは、今回プラチナスポンサーとして総勢8名で参加しました🙌 私は今回がRubyKaigi初参加なので、どんな体験が待っているのかドキドキしながら参加しました😳 RubyKaigi 2025概要 開催期間:2025年4月16日(水)〜18日(金) 開催場所:愛媛県県民文化会館 今年の開催地は愛媛県🍊 特産品のみかんにちなんだオレンジ色のロゴがとても印象的です✨ RubyKaigiでは毎日さまざまなセッションとブースが開かれており、いろいろと回ったので、その気づきや学びをご紹介します🗣️ セッション参加レポート✍️ 「Ruby Taught Me About Under the Hood」 / @ima1zumi さん Unicode(ユニコード)についてのご登壇です! そもそも私はUnicodeというものを知らなかったのですが、 とても面白かったです。 以下、登壇の内容を少しご紹介します🤏 Unicodeとは、世界の様々な言語、書式、記号に、番号を割り当てて定義した標準の文字コード。 1つひとつの文字に番号を割り当てることで、プログラマーは、どの言語が混ざっていても、コンピューターに保存、処理、伝送させるような文字エンコーディングを同じファイルやプログラムの中に作ることができるらしいです💭 そして、そのUnicodeには、 書記素クラスタ というUnicodeテキストを1文字ずつ分割するアルゴリズムがあるようです💡 分かりやすく言うと、Unicodeにおいて自然な“1文字”を表す単位です! 書記素クラスタの概念がないと何が起きるのか? 例えば「🧑‍🧑‍🧒←この絵文字は何文字ですか?」と聞かれたら、 多くの方が1文字と答えるのではないでしょうか? しかしながら、実はこの🧑‍🧑‍🧒は、 ①👨 ②""  ③👩 ④"" ⑤👦 ⑥""  ⑦👧 この7つの要素からなっているそうです😳 人間は、🧑‍🧑‍🧒=1文字 機械は、 🧑‍🧑‍🧒=7文字 と捉えるこの差分が、バグの原因になるとのこと。 そこで人間が1文字と捉えるものを機械が1文字と捉えられるようにしたのが 書記素クラスタ なのだそうです💡 絵文字の書記素分割の表を眺めてみるのも、面白かったです! 「Goodbye fat gem 2025」 / @ktou さん Fat gemについてのご登壇です! またまた私はFat gemがなんなのか知らなかったのですが、 Fat gemとは、ビルド済みバイナリー(0or1の二者択一)が入ったgem(便利な機能やよく使う機能を、あらかじめ部品化したようなもの)のこと。 つまり、すごく便利なものなのだということがわかりました。 しかしながら、作る側は大変なのだということをお話いただきました。 具体的には以下の3点が大変なポイントなのだそうです。 環境設定が難しい 脆弱性対応が遅れがち メンテナンスが大変 この3点について、少しだけ詳細を綴ります。 環境設定が難しい →Fat gemはリリースに時間がかかるし、requireにも時間がかかるため、Rubyを使う環境がなかなか整わない。 脆弱性対応が遅れがち →Fat gem内にある外部ライブラリに脆弱性が見つかった際の修正が大変。 メンテナンスが大変 →Fat gemは通常クロスコンパイルして作るのに対し、多くの外部ライブラリがそうでないため、外部の外部ライブラリが修正される度に問題が起きてしまう。 このような理由で作るのが大変になっているようです。 なんとなく使っていたRubyですが、Rubyをサポートするこのようなシステムがあって初めて使えるものなのだということを理解しました💭 「Matz Keynote」 / @yukihiro_matz さん AI時代のプログラミングについてのご登壇です! 「アルファシンドローム(犬が甘やかされていくうちに自分が家族の中のリーダーだと誤認してしまい、言うことを聞かなくなっていく現象)と逆の現象が、人間とAIの関係の間で起こるのではないか」ということを危惧する内容でした。 つまり、人間がAIさまさまになってしまうということです。 そこで重要なのが、何をAIにお願いして、何を自分でやるのかをしっかり考えることです💡 例えば、人間がやるべき仕事として、顧客の意向の汲み取りが挙げられていました。 私としては現状すでに「AIさまさまです」と思うことが多々ありますが、今後AIアシストコーディングに取り組んで行くにあたり、まさにこの考え方は重要なことだと感じました。 DrinkUpでの学び🍺 RubyKaigiの素敵なところはセッションから学ぶだけでなく、スポンサー企業が開催するDrinkUpイベントでカジュアルにお話しながら学びを深められることです!私が初学者であることを伝えると、とても熱心に教えてくれました。 例えば、基礎の基であるオブジェクト指向について。 「オブジェクト指向というのは、簡単に言うと、鳥という「もの」が飛ぶという「動作」をするという関係性を定義したり、鳥というものの「クラス」(〇〇科など)を定義したりできる、そういう考え方だよ〜」と初学者にわかりやすい例を用いて教えてくださいました💡 とてもわかりやすくて、今までよりイメージが湧いた気がします💭 Rubyに精通された方たちと近い距離でお話できる貴重な機会でした! 他社ブースでの学び📖 個性豊かなブースが勢揃いで、どこから回ろうか迷いました💭 2日目からは各ブースを回るスタンプラリーも行われていて、とても盛り上がっていました✨ そんな中、私が1番に入ったのは転職ドラフトさんのブース。 Rubyが選ばれ続ける理由を技術トレンドの変化に基づいてご説明いただきました! RubyKaigi 2025 転職ドラフトPRトーク - Speaker Deck speakerdeck.com エンジニアとしてどんな力を身につけたいか付箋に書いて貼るというワークにもチャレンジ💪 私は新卒未経験ということで、「プログラミング基礎力」と大きく書きました✍️ 各ブースでそれぞれの専門領域におけるトレンドを知ることができ、勉強になりました。 スタメンのブース出展🙌 私たちもブースを出展しました! 私たちは、自社サービス『TUNAG』のベネフィット機能を用いて、抽選イベントを行いました!当選された方には、モバイルバッテリーをプレゼント🎁 多くの方に『TUNAG』の実際の画面を見ていただけて、嬉しかったです☺️ 感想💭 私が何より言いたいのは、Rubyコミュニティーが 熱くて優しいコミュニティー だということです😌 自分が初学者であることに、はじめは引け目を感じていましたが、終わるころにはすっかりそんな気持ちも消え去っていました。 それから、 Ruby学習への意欲の高まり も感じています。 カンファレンスの内容が今年は全然わからなかったけれど、1年間学んだ来年だったらどれくらいわかるようになるだろうかというワクワクや、今年出会えたRubyistの皆さんともっと熱く語れるように、「まずは自分の知識量を増やしていかなくては!」という意思が芽生えたと思います。 そういう意味で、入社直後にこのような温かいコミュニティーで今後の学習モチベーションを高められた私は、とても恵まれたなと思っています。 来年のRubyKaigiに成長した私で戻って来られるよう、日々精進です💪 また、今年はブースの出展のみだったのですが、来年はDrinkUpの企画にも挑戦し、Rubyコミュニティーとのつながりをさらに深めていきたいと思っています🔥 イベント登壇のお知らせ📢 実は、 「はじめてのRubyKaigi 〜ゆるっとふりかえり会〜」 というイベントで登壇することになりました✨ 日時:2025年5月20日(火)19:00~ 開催場所 : primeNumber Office Lounge (目黒駅直通) 参加費用 : 無料 このイベントでは、私がはじめてRubyKaigiに参加して学んだことや心境の変化などを等身大でお話しする予定です。 少しでも興味をお持ちいただけましたら、ぜひチェックしていただけたら嬉しいです! 詳細はこちらのリンクからご覧いただけます! pn-developer-lounge.connpass.com 一緒に学び、交流できることを楽しみにしています😊 おわりに🌷 最後まで読んでいただきありがとうございます😊 スタメンでは、RubyやRubyコミュニティが好きなエンジニアを絶賛募集中です🙌 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
アバター
はじめに こんにちは! 株式会社スタメン にバックエンドエンジニアとして 2025年1月 に入社しましたもりしたです。 これまでは主にRubyを使ったバックエンド開発に携わってきました。現在は、SRE(Site Reliability Engineering)やDevEx(Developer Experience)の向上をミッションとするプラットフォーム部に所属しています。 この記事は、 スタメンの採用サイトを見て、少しでも興味を持ってくださっている方 カジュアル面談を受けてみようか迷っている方 実際に入社したメンバーの「生の声」を聞いてみたい方 に向けて書いています。 入社から約4ヶ月経過した今、肌で感じているスタメンのリアルな姿をお伝えすることで、皆さんの疑問や不安を少しでも解消できれば嬉しいです。 スタメンを選んだ理由 - 新たな技術領域への挑戦と、運用経験への意欲 私がスタメンを選んだ理由は、大きく分けて二つあります。 一つは、SRE(Site Reliability Engineering)やDevEx(Developer Experience)といった、これまで深く関わることがなかった新しい技術領域に挑戦できる環境への強い期待です。自身のスキルセットを広げ、より市場価値の高いエンジニアを目指したいと考えていました。 そしてもう一つは、プラットフォーム部でシステムの安定稼働を支えるための知識やスキルを習得したいという強い意欲があったからです。これまでの開発経験に加え、インシデント対応の調査や分析といった運用経験を積むことは、エンジニアとしての幅を広げる上で不可欠だと考えています。 カジュアル面談では、主にスタメンの事業内容や技術スタック、チームの雰囲気などについてお話を伺いました。その中で、プラットフォーム部がシステムの信頼性向上に重要な役割を担っていることを知り、開発だけでなく、運用という側面からもサービスを深く理解し、貢献できる環境に魅力を感じました。 スタメンの 経営理念 ページに書かれている Our Value(行動指針) の1つに 「Work Bravely(大胆に攻め、失敗や挑戦を讃える)」 があります。私はこの Value に背中を押され、未経験の領域にも積極的に踏み出すことを後押ししてくれる文化があると感じ、運用経験を通じて得られる知見は、今後の開発業務においても必ず活かせると確信し、入社を決意しました。 現在の業務内容 - 新しいことへの挑戦と学びの日々 プラットフォーム部の一員として、現在は主に以下の業務に携わっています。 ライブラリのバージョンアップ対応 : アプリケーションの安定性とセキュリティを常に高いレベルで維持するため、Dependabot を活用し、原則として平日毎日ライブラリのバージョンアップ対応を行っています。日々の小さな変更を積み重ねることで、常に最新の状態を保ち、セキュリティリスクを最小限に抑えています。バージョンアップの際には、影響範囲の調査や動作確認を丁寧に行い、システム全体の理解を深めています。 プロジェクトメンバーとしてのバックエンド開発 : プラットフォーム部のミッションであるSRE/DevEx向上に繋がる開発だけでなく、プロダクト開発のプロジェクトにもバックエンドエンジニアとして参加し、機能開発などを担当しています。最近では、TUNAGが提供するタスク機能に関わる開発に携わっています。 オンコール担当 : システムに問題が発生した際に迅速に対応できるよう、チームメンバーと交代でオンコール対応も行っています。スタメンでの経験はまだ浅く、原因特定に時間がかかることが多いですが、チームメンバーの協力を得ながら緊張感と責任感を持って取り組んでいます。 プラットフォーム部では、現在少数のメンバーで、SREやDevExに関わる幅広い業務を協力して進めています。ライブラリのバージョンアップ対応、機能開発のサポート、オンコール対応などを担当する中で、それぞれの得意なことや興味のある分野で助け合いながら、日々業務に取り組んでいます。少人数のチームだからこそ、お互いのスキルや知識を補完し合いながら、幅広い技術領域に触れることができています。 github.com biz.tunag.jp 入社して分かったスタメンの特徴 - 期待を超えたリアル 実際に入社してみて、「なるほど、スタメンはこういう会社なのか!」と感じた特徴をいくつかご紹介します。 技術的な特徴 - 常に進化を求める姿勢 Dependabotによる継続的なライブラリ更新 : Dependabotを活用した自動更新の仕組みがしっかりと根付いており、常に最新の技術を取り入れ、セキュリティリスクを低減する意識の高さに驚きました。 トランクベース開発 : 頻繁なマージと迅速なフィードバックループにより、開発スピードと品質の両立を目指すトランクベース開発を採用していることで、チームの一体感と効率的な開発を実感しています。 AI技術の積極的な活用推奨 : 開発効率や生産性向上のため、GitHub Copilotなどを多くのエンジニアが利用しており、新しい技術へのアンテナの高さと、それを積極的に取り入れようとする文化を感じています。Devin の活用状況については、 こちら のブログ記事をご覧ください。 組織的な特徴 - フラットな連携と成長支援 東京・名古屋の二本社制とフラットな連携 : スタメンは東京と名古屋に本社を置く二本社制を採用しており、エンジニアは両オフィスに在籍しています。しかしながら、物理的な距離を感じさせないスムーズなコミュニケーションが取れており、拠点に関わらずチームとして一体感を持って働けています。 社員コミュニケーション促進の仕組み : 社員同士の交流を活発にするため、社内での懇親会や部署を超えての交流イベントなどを定期的に開催しています。 技術カンファレンスへの積極的な参加支援 : 会社として、エンジニアの成長を支援するため、技術カンファレンスへの参加を積極的に推奨し、参加費用の補助などの支援制度を設けています。最近では、RubyKaigi 2025 に他部署を含めたバックエンドエンジニア全体で参加し、最新のRuby言語に関する動向や他社のエンジニアとの交流を通じて多くの刺激を受けました。カンファレンスで得た知識や刺激は、日々の業務における議論のきっかけとなるだけでなく、エンジニアとしての成長の糧となっています。 rubykaigi.org 会社の雰囲気 - 挑戦を後押しするカルチャーとオープンな対話 賞賛を大切にする文化 : 日々の業務における成果や貢献に対し、部署や役職に関わらず互いに賞賛を送り合う文化が根付いています。 オープンなコミュニケーション : 部署や役職の垣根を越えて気軽にコミュニケーションが取れる雰囲気があり、会社全体の動きや目標を共有しやすい環境です。 東京オフィスの特徴 : 私が所属する東京オフィスは、ビジネスサイドのメンバーが多く、オフィス全体が活気に満ち溢れています。様々な部署のメンバーが活発にコミュニケーションを取っており、エネルギッシュな雰囲気の中で業務に取り組むことができます。 さいごに 入社してまだ日は浅いですが、技術的な挑戦ができる環境、そして部署や拠点を越えて協力し合う組織文化の中で、日々多くのことを学び、刺激を受けています。 この記事を読んで、スタメンに少しでも興味を持っていただけたら嬉しいです。 スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 プラットフォーム部に興味を持っていただけましたら、Site Reliability Engineer (SRE)、ソフトウェアエンジニア(Developer Experience)からご応募ください。皆さんとお話できるのを楽しみにしています。 最後までお読みいただき、ありがとうございました。 herp.careers herp.careers herp.careers
アバター
みなさん、こんにちは!初めましての方は、初めまして! 2025年4月より株式会社スタメンにジョインしました、iOSエンジニアのとんとんぼ( @Ktombow1110 )こと、村岡です! 2025年4月9日から11日で開催された try! Swift Tokyo 2025 に弊社から、3名のメンバーで現地参加してきました! 今回は入社エントリ含めて、印象に残ったセッションや会場の雰囲気などをお伝えできればなと思います。 try! Swift とは try! Swift とは、Swift を使った開発のノウハウや最新の事例を学び、共有するために世界中の開発者が集う国際的なイベントです。日頃の Swift 知識やスキルを披露し、協力し合うことを目的に開催されます。 tryswift.jp イベントの主なプログラムは、基調講演、LT(ライトニングトーク)、スポンサーブース、Party(懇親会)などです。 世界中から開発者が集まるため、会場には様々な国籍の方がいらっしゃいます。 そのため、セッションは基本的には英語で行われますが、英語が苦手な方、または日本語が苦手な英語話者に向けて通訳が行われます。 今回のイベントでは、通訳に AI 同時通訳サービス「 Flitto 」が導入され、公式アプリを通じてリアルタイムで翻訳された発表を聞くことができるようになりました。 Flitto の紹介 今回の開催地紹介 昨年は、渋谷のベルサール渋谷ファーストで開催されました。 昨年のイベントの様子や感想については、弊社の青木( @38Punkd )が記事を公開しているので、ぜひご覧ください。 tech.stmn.co.jp 今年の会場は、立川市にある立川ステージガーデンです。 会場周辺は自然が豊かで、近くに飲食店も多く、非常に過ごしやすい場所だと感じました! 季節もちょうど桜の時期で、隣接する昭和記念公園で桜を楽しむ参加者も多く見られました。 さらに、会場自体も本格的なシアターの雰囲気で、セッションを聴くには最高の環境だったと思います。 立川ステージガーデンの入り口 会場内の様子 Swift 10周年! イベント内容 さて、ここからイベントの内容について触れていきます。 気になったセッション 今回はLTも含めて33人の方が登壇されました。 全ての方を紹介するのは難しいので、個人的に勉強になったセッションを紹介していこうかと思います。 素早く実現する優れたアプリデザイン 今回の try! Swift の中で、私が最も感動し、まさに「最推し」と言えるセッションがこちらでした。人気カメラアプリ『Halide』の開発者であるSebastiaan de With 氏が登壇し、アプリケーションのデザインや「より良いものを作るためにはどうすれば良いか」という本質的な問いについて、『Halide』を実例に解説してくれました。 このセッションで語られた、ユーザー体験を追求するための強いこだわりは、まさに弊社の Value である “Far Beyond” の精神にも通じるものがあると感じました。 私はこのセッションに感動して、残り2日間を Halide をインストールして写真を撮っていました。とても体験が良かったので、おすすめです! youtu.be J1プロサッカーチームFC町田ゼルビアのImmersive動画を撮影しSwiftでViewerを実装し体験会実施した Cyber Agent に所属し、 visionOS Engineer Meetup も主催されている服部さんのセッションです。 サッカーJ1リーグ所属の FC町田ゼルビアの Immersive Video(没入型映像)を撮影し、特別会員向けに実施した体験会で得られた貴重な知見についてお話を伺うことができました。 実際に体験したユーザーから「楽しかった」とコメントがあり、エンジニア冥利に尽きるなぁと聞いていて思いました。 体験会に参加したユーザーから寄せられた「(普段見られないアングルから観戦できて)楽しかった」といった直接的なコメントも紹介され、こうした新しい価値を提供できることは、まさにエンジニア冥利に尽きる体験だなと感じました。 youtu.be SwiftUI 8番出口 SwiftUI で UI を実装する際、特定の課題に直面したとき、SwiftUI で解決策を探るべきか、それとも UIKit の力を借りるべきか、この開発者がしばしば悩むであろう判断を、『8番出口』というゲームをモチーフに、ゲーム感覚で解説していくユニークな LT でした。 ゲームの世界観を巧みに再現しており、随所に細かい小ネタも満載で、まさにLTらしい遊び心にあふれた構成で非常に楽しい内容でした。 発表中、会場からは何度も笑い声が上がり、とても和気あいあいとした雰囲気の中で、楽しみながら聴くことができました。 youtu.be スポンサーブース スポンサーブースも非常に充実していました。例えば、参加者が try! Swift のタイムテーブルアプリ開発ができるブースや、ルーレット・くじ引きなどで素敵な景品が当たる企画など、各社が訪問者を楽しませるための趣向を凝らしたコンテンツを多数用意しており、本当に盛りだくさんでした。 ステッカーを当てて浮かれるエンジニア 私は、「売上猫」こと RevenuCat のスポンサーで当てた売上猫ニット帽を2日目と3日目にずっとつけてブースを回っていました。 Party の雰囲気 イベント2日目の最後には、懇親パーティーが開催されました。今回は会場近くにある開放的な屋外スペースでの開催でした! 様々な方々とおしゃべりしたり、音楽に合わせて踊ったりと、リラックスした雰囲気の中で交流を楽しむことができ、とても楽しい時間でした。 屋外DJブース try Swift 公式アプリについて try! Swift の公式イベントアプリはオープンソースで公開されています。 私は毎年、参加するカンファレンスやイベントの公式アプリには、少なくとも1つのPull Request を送って何らかの形で貢献することを個人的な目標にしています。これは、エンジニアとして技術コミュニティに少しでも貢献したいという思いから、自主的に続けている活動です。 今年は、アプリ内で使用されているライブラリの謝辞表示に関する修正の Pull Request を送りマージしていただきました。拙い英語力のため、やり取りでメンテナーの方を困らせていますが、今年も微力ながら貢献できて嬉しく思っています。 github.com 来年もまた開催することが決まったら、貢献していきたいと思います! 全体の感想 今年の開催が平日だったことに加え、私自身が入社直後のタイミングだったこともあり、当初は参加を見送るつもりでした。しかし、入社したらすぐに「try Swift 行きます?もう話はしてるので、参加するなら稟議出してください」と言われ、快く爆速で送り出していただきました。いやー、あったけぇ 昨年はプライベートで一人参加でしたが、今年は職場のエンジニア同僚2名と一緒にブースを回ったり、セッションを聴いたりと、終始とても楽しく過ごすことができました。 セッションでは、技術的な知識はもちろんのこと、プロダクト開発に向き合う情熱や心構えに触れることができ、多くの面で良い刺激を受けました。 また、今年の会場が立川だったことも、自然豊かな環境で、リラックスしてセッションに集中できた点でとても良かったと思います。 今回の経験を糧に、これからも業務・個人活動問わず、iOSの開発に一層力を入れていきたいと思います!来年の try! Swift Tokyo 開催も楽しみにしています! 会場隣りのカフェでチルするiOSエンジニア達 採用情報 株式会社スタメンは、iOSエンジニアはもちろん、全ての領域でエンジニアを募集しています! もし、興味を持っていただけたら、下記からご応募ください! herp.careers
アバター
プロダクト開発部でTUNAGの開発をしている hisa です。 私たちの開発チームでは、プロダクトをより良く育てていくために、日々の開発の進め方やチームの体制について、試行錯誤を重ねてきました。 ただ、新機能の開発や日常的な対応を優先する中で、「手を入れたいのに後回しになってしまう」タスクが少しずつ積み上がっていく感覚もありました。 そうした状況を見直し、開発の質とスピードのバランスを取り戻す一手として、私たちはDevinの導入に踏み切りました。 この記事では、Devinをチームに迎えてからの変化や、活用における工夫についてご紹介します。 Devin導入の背景 プロダクトを継続的に成長させていくためには、機能開発だけでなく、基盤の見直しや細かな改善対応といったタスクにも継続的に取り組んでいく必要があります。 たとえば、 プロダクト全体のリアーキテクチャ ライブラリアップデート(影響範囲の調査含む) 社内やお客様から上がった改善アイテム こうしたタスクは、いずれもプロダクトの健全性やユーザー体験に関わる重要なテーマですが、どうしても日々の開発サイクルの中では優先度が上がりにくく、着手のタイミングを逃してしまいがちです。 私たちは、これらのタスクを「後回しにしない」ためだけでなく、チーム全体としての開発力を底上げし、より本質的な課題に集中できる体制をつくる一手としてDevinを導入しました。 Devinを使いこなすための5つのTips 1. タスクは10〜15分で完了する粒度に分割する 長時間タスクをそのまま渡すと 作業の途中で認識がズレてしまう 関連ファイルの参照漏れや飛躍した実装が起きる 要件を誤解したまま進行してしまう といったリスクが高くなります。 そのため、タスクは 「遅くとも15分以内に終わる」 ことを目安に分割しています。 2. 実装方針は必ずテキストですり合わせる Devinは仕様を聞かずに実装を始めることがあります。 実践しているのは、PRではなく、 テキストベース で方針のすり合わせを行うこと。 Issue〇〇の対応をして欲しいです。 実装前に実装方針をIssueのコメントに記載してください。 ---> 実装方針をコメントに記載しました。 Buttonコンポーネントはすでに〇〇で実装されています。修正お願いします。 ---> 修正案をコメントに追加しました。 実装提案確認しました。 実装のボリュームが大きくなってきたので、Issueを小分けにしていただけますか? ---> ご提案いただいた通り、以下の3つのIssueを作成します。 では1の実装からお願いします。 といった流れを踏んでから作業を任せています。 3. DevinにIssueを書かせる Issueなどがない場合、いきなり作業させるのではなく、 まずIssueを書かせる 運用にしています。 背景 ゴール 作業内容 上記を自分で整理させ、そのIssueをそのまま着手させることで実装精度が安定しました。 4. 「やらないこと」を明確にする Devinは善意で リファクタリング 不要なテストの追加 エラーハンドリングの強化 など、 依頼していない作業 をすることがあります。 例えば「今回はテストは追加しないで」「リファクタリングは不要」など、 やらないこともセットで指示 するようにしています。 5. 作業ログは逐次出力させる 作業中に「何も言わずに進めてしまう」ことがよくあります。 常に「今、何をやっているか説明して」「進捗を逐次共有して」とお願いすることで、進捗の見える化と、早期の異常検知ができています。 Devinを活用したタスク例 リアーキテクチャ 現状整理・リファクタ方針作成・Issue分割・実装・テスト ライブラリアップデート Release Note読解・プロダクト内の利用箇所特定・影響レポートの作成 改善アイテム 社内やお客様から上がっていた改善アイテムの実装 Devinが特に得意だったタスク 振り返ってみると、下記のように インプットとアウトプットのイメージが明確なタスク は、特に安定して対応できるようになってきました。 API実装 バリデーション追加 ロジック単体の改善 設定・スクリプト系の作業 一方で、デザインやUI実装など、Figmaを読む前提のタスクは現状ではそこまで得意ではありません。 BoltなどはFigmaを読み取り対応していますが、Devinも今後は対応するのではないかと期待しています。 よくあった失敗と改善 課題 原因 改善策 勝手に設計変更 方針すり合わせ不足 事前にテキストで確認し、ナレッジ化 実装精度の低下 タスクが重すぎた 10〜15分単位に分割 同じ質問を繰り返す コンテキストの欠落 or 曖昧な依頼 前提・背景・制約条件を毎回セットで共有し、必要なら「ナレッジとして記憶させる」 余計な作業を実施 やらないことを指示していない やらないことも明示する Devinに実際に渡したIssue例 # Issue: ラジオボタンのキーボード操作に対応 ## 内容 現在のラジオボタンがキーボードで正しくフォーカスされない。アクセシビリティ改善のため、Tabキー操作での移動&選択に対応したい ## やること - components/RadioGroup/index.tsx を修正 - role =radiogroup、aria-checked などの属性を適切に付与 - Tab / Shift+Tab / Enterキー で操作可能にする ## 補足 - スクリーンリーダーでの読み上げ確認は不要(別Issueで予定) ## やらないこと - ラジオボタンのデザイン変更 - フォームロジックの修正 Devin導入の効果 着手のハードルが高かったタスクにも手が伸びるように 「気になっていたけれど後回しになっていた」タスクが少しずつ片付いていくようになりました。 小規模な改善Issue ライブラリのアップデートと影響調査 デッドコードの整理や命名統一 など Devinを活用することで、こうしたタスクに手が届きやすくなり、コードベースの健全性向上にもつながっています。 重ための開発にも踏み込みやすくなった プロダクト全体のリアーキテクチャ方針の策定・実装 モジュール単位での構成見直し レガシーな一括バッチの分解・再構成 Devinにまず「現状把握」→「方針案の提示」→「タスクへの分割」までを任せることで、全体像がつかみやすくなり、チームとして動き出すための一歩が軽くなりました。 PR作成数が約1.5倍に増加 定常的な改善タスクをDevinに任せられるようになったことで、メンバーはより注力すべき領域に集中しやすくなりました。 単純なPR数の増加だけでなく、「対応が早くなった」という声もあり、チーム全体のリズムが良くなってきた感覚があります。 「まずDevinに任せてみる」が自然な選択肢に 「ちょっと時間かかりそうなタスク」を見つけたら「まずDevinに投げてみる」が自然なフローに Slack上でも「このIssueDevin向きかも?」というやり取りが増加 文化として根付いた と感じられるのは、大きな成果のひとつでした。 まとめ Devinは、すべてを自動で解決してくれる存在ではありません。 ですが、タスクの粒度を整え、進め方を丁寧に伝えることで、着実に動いてくれる「チームの一員」になり得ます。 導入したことで、これまで着手しにくかったタスクにも少しずつ向き合えるようになり、 さらに大きな変化としては、人が「人にしかできないこと」に集中する時間が増えてきたことがあります。 たとえば、プロダクトの方向性を考える、設計を詰める、チームで議論するといった創造的な時間です。 そうした本質的な領域に、より多くのリソースを割けるようになったことはチームにとって大きな前進でした。 AIに任せるところは任せて、人は人としての強みを発揮する。 Devinは、そのバランスを取り戻すための、ちょうど良いきっかけになってくれています。
アバター
株式会社スタメンのTUNAGプロダクト開発部で Android アプリを開発しているカーキ(X: @khaki_ngy )です。 自分はスタメンには2020年に新卒入社しており、6年目の春が始まりソワソワした気持ちを抱いています🌸 直近、TUNAGの機能開発で AlarmManager の API を利用し、指定した時間にローカル通知を発行する機能を開発しました。 AlarmManager 自体はかなり古くからある API ですが、権限周りで Android12 から変更が加えられるなど近年のセキュリティ強化の影響も受けています。 今回のブログでは、AlarmManager を利用する一連の流れと、プロダクションで運用するための注意事項を紹介します。 AlarmManager とは AlarmManager とは android.app API に存在するクラスであり、指定した時間に特定の処理を実行することができます。 アプリが起動していない状態(バックグラウンドにいる状態)でも、指定の時刻に処理を行うことができます。ユースケースとしては時計アプリのアラーム機能などでユーザーが指定した時刻にアラームや通知を発行するような時に利用されます。 今回 TUNAG では、指定された日時にローカル通知を発行するために採用しましたが、本当に AlarmManager を使うべきかどうかの見極めが必要です。 なぜならば、先述した通り AlarmManager は指定した時刻でバックグラウンドで強力な処理を実行できるポテンシャルがあるためです。正確な時刻にバックグラウンドで処理を起動できること自体が、バッテリーやリソースに影響を与える可能性があるため、AlarmManager を使って正確な時刻にアラームを設定するには後述する特別なアプリアクセス権の取得が必要になります。ユースケースに応じて、本当に AlarmManager を利用するべきかどうかを一度考えた方が良いでしょう。 代替手段との比較では、正確な時間指定が必要かどうかが軸になってきます。 正確な時間指定が必要でない場合、代替手段として公式ドキュメントでは Handler クラスの利用や、 WorkManager での定期実行のスケジュールなどが紹介されています。WorkManager はライフサイクルの考慮や、処理を開始する上でのシステム的な制約を指定することができるので、遅延実行して問題のないバックグラウンド処理であれば WorkManager を利用するのが良いでしょう。 AlarmManager と権限 権限の種別 AlarmManager を利用して正確な時間に処理をスケジュールするには、以下の権限のうちどちらか一つが必要になります。 USE_EXACT_ALARM SCHEDULE_EXACT_ALARM どちらの権限も AlarmManager を通して、正確な時間に処理をスケジュールするのに必要な権限になりますが、どのような機能を提供するアプリかに応じてどちらの権限を利用するかが変わります。 前者の USE_EXACT_ALARM は、 アラーム・カレンダー機能が主となるアプリ向け の権限になります。Android の APIレベル33(Android 13相当)から登場した権限です。 アラーム・カレンダーアプリが主の機能となっていれば、指定の時刻に処理を行なったり、通知を送ったりする機能はほとんど必須の機能となります。そのため、AndroidManifest で権限の利用を宣言していれば、ユーザーの許可なしで正確な時間の処理が可能になります。 ただし、前提となっている アラーム・カレンダーアプリがメインの機能かどうか という点がアプリの審査で判断されることになります。アラーム・カレンダー機能が主となるアプリでない場合は、こちらの権限を利用してもストアへの公開は難しいでしょう。 後者の SCHEDULE_EXACT_ALARM は、前者の対象となる「アラーム・カレンダー機能が主となる」アプリ 以外 を対象とした権限になります。こちらはAndroidのAPIレベル31(Android 12相当)から登場した権限です。 こちらの権限では、アラームやカレンダー機能を主としたアプリ以外での利用を想定されています。 こちらの権限は Android の API 34以降(Android 14相当)では、デフォルトで拒否されるようになっており、ユーザー自身がアプリに「アラームとリマインダー」の権限を許可する必要があります。 「アラームとリマインダー」は特別なアプリアクセス権に分類され、通常の権限リクエストとは若干方法が異なり、設定画面でユーザーに『許可』をしてもらう必要があります。 システムのアプリ設定内にある「アラームとリマインダー」 正確な時間のアラームであっても AlarmManager の OnAlarmListener オブジェクトを利用する場合は、 SCHEDULE_EXACT_ALARM は不要になります。ただ OnAlarmListener を利用したアラームの場合はアプリのプロセスが生きている期間の間は有効になりますが、アプリキルをされた場合などプロセスが終了している状態では、アラームを起動させることができません。この後の内容に関しても OnAlarmListener を利用せず、バックグラウンドでも機能するスケジューリング処理について紹介をしていきます。 権限のハンドリング 先述の通り、AlarmManager による(バックグラウンドで動作する)正確な時間での処理のスケジュールには、 SCHEDULE_EXACT_ALARM 権限が必要になります。 権限を獲得するフローは大体以下の流れです 1. ユーザーがすでに権限を持っているか確認する 2. 持っていなければ、権限のリクエストを要求する 1. 権限の確認 通常、権限の許可がされているかを確認する場合には ContextCompat.checkSelfPermission を利用して、対象のパーミッションが許可されているかどうかを確認します。ただ SCHEDULE_EXACT_ALARM は特別な権限となるため、AlarmManager に用意されている専用のメソッド canScheduleExactAlarms() を利用して確認する必要があります。 ( ContextCompat.checkSelfPermission で確認しても常に許可されていないと返ってきてしまいます) 具体的なコードのイメージとしては以下のようになります。 val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager // Android 12 より前、もしくは権限が許可されている場合 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || alarmManager.canScheduleExactAlarms()) { // alarmManagerによるスケジューリングを実施 } else { // 権限をリクエストする } 2. 権限のリクエスト 権限が許可されていない場合は、ユーザーに権限をリクエストする必要があります。 一般的な権限のようにアプリ内のダイアログで権限リクエストをする仕組みが用意されていないため、設定画面に遷移させて、ユーザーに設定を変更してもらう必要があります。 以下のように『アラームとリマインダー』に関する設定ページに直接遷移するようなIntentを発行することで、ユーザーを設定画面に導くことができます。 val intent = Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM) startActivity(intent) 上記では単純な Intent 遷移の例を示していますが、Activity Result API による遷移を利用すれば、設定画面から戻ってきたタイミングをハンドルできるので、より状況に適した処理を実装できると思います。 権限リクエスト時の注意点 SCHEDULE_EXACT_ALARM はシステムでの権限付与のダイアログが提供されていないため、アプリからユーザーに対して権限リクエストの旨を伝えるのが良いでしょう。 権限の付与が必要なタイミングで突然システムの設定画面に飛ばされてもユーザーは困惑してしまうためです。 そのため、下記のようなダイアログを一つ挟んで、アラームの設定を行うかどうかをユーザーに事前に確認をすると良いです。 ユーザーに向けたダイアログの例 AlarmManager を利用する 指定した時間にアラームをスケジュールする AlarmManagerによりアラームをスケジュールする流れとしては、以下の2ステップです。 PendingIntent を作成 AlarmManager インスタンスからスケジューリングのメソッドを実行 それぞれについて解説していきます。 1. PendingIntent を作成 指定した時間にアラームを受け取る際に BroadcastReceiver を利用し、バックグラウンドでも BroadcastReceiver を受け取れるように PendingIntent を作成します。 この際、アラームのスケジュールを設定する上で考慮するべき点がいくつかあります。 val pendingIntent = PendingIntent.getBroadcast( context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE ) まず getBroadcast の第二引数になっている requestCode です。 これは予約するアラームを一意に識別する役割があります。そのため、例えば、同じ requestCode で複数アラームをスケジュールしても、最後にスケジュールした PendingIntent しか有効になりません。 また後からスケジュールしたアラームをキャンセルしたい場合にも同じ requestCode から作成された PendingIntent が必要になります。 次に第三引数として指定している intent についてです。 この Intent は、アラームが起動した時に実行させたい BroadcastReceiver に向けられた Intent を指定してください。 val intent = Intent(context, MyAlarmReceiver :: class .java).apply { putExtra(MESSAGE_KEY, "アラームです" ) } この intent に対して、 action や extra を指定することができるので、これらを指定することで、 BroadcastReceiver の中で処理に必要な情報を渡すことができます。 第4引数の PendingIntent のフラグに何を渡すのかでもアラームの挙動が少し変化します。 PendingIntent.FLAG_IMMUTABLE は、PendingIntentの中身が他のアプリによって変更されることを防ぐフラグになります。Android API 31以降では PendingIntent.FLAG_IMMUTABLE 、 PendingIntent.MUTABLE のどちらかが必須となっています。アプリによってどちらを選択するべきかは異なりますが、他のアプリによって遷移先が勝手に書き換えられてしまう可能性があるので、基本的には PendingIntent.FLAG_IMMUTABLE を設定しておいた方が良いでしょう。 また PendingIntent.FLAG_CANCEL_CURRENT は既に同じ requestCode で生成されたPendingIntentがある場合に前の内容をキャンセルして、新たなPendingIntentとして登録するために設定をします。 近いものとしては PendingIntent.FLAG_UPDATE_CURRENT というフラグも存在します。こちらは同じ requestCode で生成されたPendingIntentがある場合に、中のIntentだけを新しいものに更新するフラグになります。 requestCode を被らないように設定している場合であれば、どちらを選んでも結果は変わりませんが、同じ値が入る可能性があれば、どちらを選択するべきかをよく考える必要があります。 2. スケジューリングのメソッドを使う アラームをセットするメソッドは複数存在し、アラームが「繰り返しなのか」「正確な時刻が必要なのか」に応じて適切なメソッドを選択する必要があります。 今回は1回きりのアラーム set を中心に紹介をします。 一回きりのアラームの set をいくつか種類があります。 set : 最も効率の良い1回きりのアラームメソッド。効率は良いものの、端末の状態に大きく左右されるため、指定した時刻通りに発火することは保証されていません。 setExact : set メソッドよりは正確に発火することを目的としたメソッド。ただ端末がDozeモードに入ってしまうと発火しないので注意が必要。 setAndAllowWhileIdle : Dozeモードなど、端末がアイドル状態の場合でもスケジュール通りに発火するメソッド。端末の状態に関わらず実行させたい場合はこれを利用する。 また set メソッドの第一引数にはAlarmManagerのTypeを指定する必要があります。 こちらは4種類のタイプがあります。 ELAPSED_REALTIME : デバイスが起動してからの経過時間に基づいてPendingIntentを開始する、デバイスのスリープは解除しない。 ELAPSED_REALTIME_WAKEUP : デバイスが起動してから指定された時間が経過した後にデバイスのスリープを解除し、PendingIntentを開始する RTC : 指定された時間にPendingIntentを開始する。ただし、デバイスのスリープは解除しません。 RTC_WAKEUP : 指定された時刻にデバイスを復帰させてPendingIntentを開始する。 それぞれアラームの特性に合わせて実装をするのが良いと思います。 まとめると アラームを発行する流れをまとめると以下のようになります。 val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val alarmIntent = Intent(context, MyAlarmReceiver :: class .java) val pendingIntent = PendingIntent.getBroadcast( context, requestCode, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE ) alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, notifiedDateTime.toInstant().toEpochMilli(), pendingIntent ) アラームされたタイミングで実行される処理 アラームされたタイミングで実行される処理は BroadcastReceiver で実施されるので、こちらの準備も必要になります。 class CalendarEventAlarmReceiver: BroadcastReceiver() { override fun onReceive(context: Context, intent : Intent) { // アラーム発火時に行う処理 } } BroadcastReceiver の利用には AndroidManifest での利用の宣言も必要になるので忘れずに行いましょう。 まとめ 今回は、AlarmManager を使った実装の紹介を行いました。 古くからあるAPIではあるものの、Android API 23 からの Doze モードの登場や、Android API 31 以降の権限の強化によって、ここ数年でも実装や扱い方が変わってきているAPIになります。 AlarmManagerのドキュメントには USE_EXACT_ALARM や SCHEDULE_EXACT_ALARM を利用する場合の注意点が書かれており、アプリケーションが提供したい機能に応じて、どのような方法でスケジュールをするのか(あるいは、AlarmManagerを使わないのか)を判断して利用する必要があります。 株式会社スタメンでは一緒に働く仲間を募集しています。少し気になる、話を聞いてみたい!という場合は以下のフォームからご連絡ください herp.careers
アバター
こんにちは、スタメンでエンジニアリングマネージャーをしているasashin(@asashin227)です。 近頃は暖かくなり、もうすっかり春の気候ですね。 最近、桜の盆栽を手に入れて、視覚的にも春を感じられるようになりました。 EMConfに参加してから1ヶ月ほど経過しましたが、日々の業務の中でもEMConfでの学びを振り返る事があり、自分の考えとして定着したものや腹落ちしたものなどありましたので、改めて登壇された方のスライドを見ながら振り返っていこうと思います。 2025.emconf.jp EMConf2025は2025/02/27に開催されました。(実は当日は誕生日でした) 参加レポートとしては、 @hisa が執筆した 非EMがEMConf JP 2025に参加して学んだこと 〜エンジニア視点で見るEMの役割と未来〜 をご覧ください。 tech.stmn.co.jp EMの役割 一般的にはEMの役割として以下の項目を挙げられることが多いです。 プロダクトマネジメント プロジェクトマネジメント テクノロジーマネジメント ピープルマネジメント これは、EMConfでキーノートを務められた広木大地さんが執筆した エンジニアリングマネージャー/プロダクトマネージャーのための知識体系と読書ガイド によって広く知られるようになりました。 qiita.com 今回、広木さん自らこれをアップデートし、テクノロジーマネジメントからプラットフォームマネジメントとなりました。 プロダクトマネジメント プロジェクトマネジメント プラットフォームマネジメント ピープルマネジメント hirokidaichi.github.io プラットフォームマネジメントという考え方 これまでの役割として提示されていたテクノロジーマネジメントとしては、技術負債のコントロールや、技術戦略、アーキテクチャ選定、モニタリングなど、エンジニアリングに対して直接的に関与するようなことが多かったように考えていますが、プラットフォームマネジメントという表現では、エンジニアリングはメンバーに任せつつ一歩引いたマネジメントを行う表現になったように感じています。 直接的に技術的負債を解消するための働きかけも必要ですが、技術的負債を生み出さないためのデリバリーフローの構築や、ツールの整備などを主戦場とすることと、これらが必要なタイミングでチームに提供できるように、定点観測したり、早期に失敗できる(Fail fast)できるように準備しておくことが必要となります。 また、スタメンではプラットフォーム部が存在し、プロダクト部全体に対して開発者体験の向上を行っていますが、EMの役割としても管掌組織に対しての、開発者体験と生産性の向上を担っていくとことが、プラットフォームマネジメントと捉えました。 開発者体験の向上のためのツールの導入支援やCI/CDの構築などが具体的な方法論としてはありますが、これらを戦略的に導入しつつ、メンバーにかかるコストを中長期で低下させるための技術基盤を構築、維持し続けることが、プラットフォームマネジメントと言えるのではないでしょうか。 現在の私の管掌チームでは、CI/CDの整備などのデリバリーフローの効率化を行えていますが、技術的負債のマネジメントまで踏み込むことができていないため、今後の課題となってきそうです。 エンジニアリングの価値をどう考えるか 開発生産性を語る上で、どのように経営指標と接続していくのか、例えば機能がどれほど売り上げに貢献したのかや、DXによってコスト削減し、利益率を上げるなどありますが、 エンジニアリング価値を黒字化する、バリューベース戦略を用いた技術戦略策定の道のり(by Kazuki Maeda) の中でも損益計算書(P/L)のように捉えて開発組織内で黒字化させるという手法について、以前から頭の中にはあったのですが、視覚化されることで改めて、気づきがありました。 speakerdeck.com 経営との接続を考えるとどうしても金額的なものに置き換えて語りたくなってしまうのですが、そうではなく価値提供速度を挙げていた点が、腹落ちしました。 価値のボリュームを計ろうとするとどうしても利益率や売り上げに紐付いてきてしまい、変数が多くエンジニアリングの貢献度合いが曖昧になってしまうため、この観点は非常に良いものだと感じました。 開発や運用コストを抑えつつ、早く早く価値を届けることがエンジニアリングの価値として定義してみるという試みがありそうと考えています。 サバイバルフェーズの心得 speakerdeck.com ここでの文脈でのサバイバルフェーズとはKPIの未達成や事業計画のビハインド、収益構造の悪化など事業面の事象やメンバーの疲弊と離職という状態を指しており、過去の似たような状況に遭遇したため思い出しながらセッションを聴いていました。 足元の数値改善は当然として、根本的なコスト構造改善のための方針を打ち出されていたとお話を聞くだけでかなりハードな状況だった事が伺えました。 その中でも大変参考になったのが、考える時間軸を伸ばすというお話でした。 目の前の課題に取り組み続けることのみに注力するとメンバーやマネージャー自身の目線が下がり、すべての施策が後手に回ってしまうという事が経験上ありました。 やるべきタスクが消化されず目先のわかりやすい問題に目がいってしまい、本質的な課題解決ができない状態となってしまいます。 こにふぁーさんの発表では1年半先に向けて組織とプロダクトの目線を合わせることでその中で必要な役割にチャレンジしてもらったり、重要度の高いが緊急性の低い問題に取り組む事ができるようになったと紹介されていました。 また、少し先のチャレンジングな目標が共有されることでメンバーの熱量が大きくなり、自らチャレンジしてくれるメンバーもいたとのことでした。 直近のプロジェクトが半年以内に終了するサイズ感のものが多く、1年以上先の話をメンバーとする機会が少なくなっているので(現状サバイバルモードというほどでもないですが、)私自身もっとメンバーと未来の話をせねばと思いました。 これからのエンジニアリングマネジメント キーノートの広木さん、岩瀬さんがお二人とも触れていたことでもありますが、昨今のAIの成長によってエンジニアリングマネジメントはEMだけが行うものではなくなっていくと感じました。 スタメン社内でもAIを用いた開発が徐々に浸透し始め、私自身も、ClaudeやGithub Copilotを活用しながら開発を行なっています。 チームの一部メンバーは Devin.ai を使い始めており、人間が指示して、AIが実装するということが現実になっています。 コミュニケーションしている様はまさに先輩エンジニアと後輩エンジニアのオンボーディグのように見えます。 このように、意図せずとも、AIに対しての教育やタスクの分解、指示だし、進捗管理など、マネジメントの要素は徐々にエンジニアメンバーの業務にも染み出してきています。 広木さんのキーノートにも記されている通り すべてのエンジニアは、AIをメンバーに持つエンジニアリングマネージャーになる。 ということが現実的にすでに起こっていると考えています EMでなくともEMっぽいことが求められるという未来がそう遠くない中で、我々、現在のEMはメンバーに対して、EMっぽいことをできるようになろうということを伝えていかなければなりません。 プロジェクトマネジメントやAI教育と指示出しのための言語化能力は必ず必須スキルになっていきますし、簡単な実装はAIに置き換わっていくため、より高度な技術を身につけなければなりません。 最後に テック系のカンファレンスに参加することはありますが、マネジメント系のカンファレンスは(現地参加としては)初めてだったため、他の参加者の方との交流ができたことが、最も良かったと感じる部分でした。 特に、スタメンでは専任のEMが私一人ということもあり、同じ立場だからこその悩みや具体的な取り組みの事例などのお話を聞くことができて、楽しい1日となりました。 スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers
アバター
この度、株式会社スタメンは昨年に引き続き、RubyKaigi 2025にPlatinumスポンサーとして協賛します。 昨年のRubyKaigiのレポートはこちらから👇 tech.stmn.co.jp スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「TUNAG(ツナグ)」を開発・提供しています。「TUNAG」はバックエンドの開発言語にRubyを使用しております。 事業と開発組織が成長できたのは RubyとRubyコミュニティの支えがあってこそであり、今後のさらなるコミュニティの発展に貢献するため「RubyKaigi 2025」へ協賛いたします。 本カンファレンスへの協賛を通して、これからのRubyコミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! RubyKaigi 2025 開催概要 名称 RubyKaigi 2025 開催日時 2025年4月16日(水) 〜 18日(金) 場所 愛媛県県⺠⽂化会館 (愛媛県松⼭市) 参加方法や詳細については、下記公式サイトをご覧ください 👇 rubykaigi.org 今年のブース企画について 昨年、好評だったスタメンのブースを今年も出します! 『 TUNAG 』の機能の一部を利用した、参加型ブースイベントとなっており、実際のプロダクト機能を使った抽選イベントで、来場者の皆さまにワクワクと楽しさをお届けします! 参加いただいた方には、参加賞や景品も用意しておりますので、ぜひ遊びにきてください!(数には限りがございます。) 皆さまのお越しを心よりお待ちしています! おわりに 最後まで読んでいただきありがとうございます。 弊社からはエンジニア、HR含め8名が現地参加します! ブースやイベント等でお話できることを楽しみにしています! 当日会場ではどうぞよろしくお願いいたします。 スタメンでは、RubyやRubyコミュニティが好きなエンジニアを絶賛募集中です。 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
アバター
はじめに こんにちは、プラットフォーム部の 近藤 です。 2018年に初期リリースしたチャット機能は、システムの拡張性と安定性の向上が課題となっていました。そこで、これらの課題を解決し、より快適なサービスを提供するために、2025年3月に「TUNAGチャット」をリリースしました。本記事では、このリプレースにおいて、マルチテナント型の SaaS アプリケーションをどのように構成したのかをご紹介します。 prtimes.jp 図1にアーキテクチャ全体の構成を示しました。Google Kubernetes Engine (GKE) を中心に構成しています。実際にはもっと多くのコンポーネントを用いていますが、この記事で取り上げたい内容に限定して図にしました。弊社ではこれまで、Amazon Elastic Container Service (Amazon ECS) を採用することがほとんどで、GKE の導入は今回が初めてです。 図1 全体の構成図 マルチテナントを構築する上で考慮すべきトピックは多岐にわたります。本記事では、インフラストラクチャの共有・占有という主にテナント分離の観点に焦点を当てて説明させていただきます。 ドメイン 図1で示したとおり、アプリケーションはテナントごとに分離されています。このようなサイロモデルにおいては、テナントルーティングが必要です。テナントルーティングの戦略として、(1)ドメイン駆動型ルーティング、(2)データ駆動型ルーティングの2つが考えられます *1 。図2に、それぞれの比較を簡単にまとめました。詳しくは、Amazon Web Services ブログなどもご参照ください *2 。 図2 テナントルーティング戦略の比較 今回は認証をアプリケーション側で実装する必要があったため、ドメイン駆動型ルーティングを選択しました。具体的には、各テナントに固有のサブドメインを作成し、テナントを識別しています。そしてサブドメインには、意味のない文字列ではなく、テナントごとにパーソナライズされたバニティサブドメインを使用しています。例えば、株式会社スタメンの場合、「stmn.example.com」のようなサブドメインとなります。バニティサブドメインはシステム側ではなく顧客が決定するため、運用や開発にコストが発生しますが、ユーザーエクスペリエンスを重視し、この方式を採用しました *3 。 ロードバランサー ロードバランサーは、全テナント共有のインフラストラクチャとなっています。インフラストラクチャを共有する理由は、主にコストの最適化のためです。Cloud Load Balancing は、受信・送信データ量に加えて、「転送ルール数 × 利用時間」に対する従量課金のため *4 、テナント間で共有することでコストは抑えられます。 Kubernetesクラスター内で実行されているサービスへの外部アクセスには、一般的に Ingress が使用されることが多いかもしれません。今回は図1に示すとおり、各テナントは Namespace で分離されています。Ingress は Namespace を跨いで利用することが単純にはできないため、このような場合には Gateway の使用が選択肢として考えられます *5 。Gateway は Ingress のスーパーセットとして提供されている点 *6 も、採用理由の一つです。ただし、GKE Gateway では Cloud CDN をサポートしていない点 *7 には留意が必要です。 アプリケーション 今回のアプリケーションの要件として、テナントごとに Pod を用意して、サーバーを立てる必要がありました。Pod を分離した主目的ではありませんが、テナントごとに最適なコンピューティングリソースが適用できたり、ノイジーネイバーの対策にも繋がっています。 また、各テナントの Pod は Namspace によって分離しています *8 。テナント専用 Namespace によるサイロ化には、いくつかのメリットがありました。 第一に、分離された環境により、セキュリティを強化できます。テナント間のデータ漏洩は、SaaS において非常に大きなビジネスリスクの一つです。 第二、モニタリングでの利便性です。Google Cloud のコンソール上で、Namespace 単位で各種メトリクスが確認でき、より柔軟かつ素早く分析することが可能です。 第三に、Kubernetes オブジェクトの名前の衝突を意識する必要がなくなるなど、オブジェクトの管理が容易になります。今回のアプリケーションでは、新規にテナントを追加する場合は、テナント専用の設定ファイルを追加してワークフローを実行します。解約に伴いテナントを削除する場合は、Namespace を削除することで、属するオブジェクトを一括で削除できます。こうした管理も、Namespace による分離が効果を発揮しています。 図3 ファイル管理のイメージ データベース マルチテナントにおけるデータベースの分離パターンはいくつか考えられます。(1)単一インスタンス共通データベース方式、(2)単一インスタンス個別データベース方式、(3)インスタンス分離方式などです *9 。また、RDB にとらわれず、マネージドなサービスも選択肢になり得るかもしれません *10 。今回は、アプリケーションの特性として、RDB の利用が前提となっていました。 データベースの分離パターン 単一インスタンス共通データベース方式は、インフラ費用や運用コストにメリットがあります。このパターンの場合、データ分離は PostgreSQL の Row Level Security を利用したり、アプリケーションレイヤーで対応することになります。これまで弊社のRailsアプリケーションでは、主にこのパターンを採用してきました。 今回は、アプリケーションレイヤーでデータ分離を対応することが困難だったため、単一インスタンス個別データベース方式を採用しました。テナントごとにデータベースユーザを作成し、各アプリケーションはそのユーザを利用して、データベースにアクセスします。各テナントは、別テナントのデータベースを参照することは、権限の制約によりできません。一方で、インスタンスを共有しているため、ノイジーネイバーなどはリスクとなり得ます。インスタンス分離方式は、インフラ費用や運用コストが高いため採用は現実的ではありませんでした。 図5 分離されたアクセスのイメージ 単一インスタンス共通データベース方式を採用している弊社の Rails アプリケーションでは、activerecord-multi-tenant *11 という Gem を用いて、アプリケーションレイヤーでデータ分離を実現しています。ただし、Gem による制約の適用を確実にするため、弊社では独自のテストコードを実装するといった様々な工夫が必要になっており、その対応は簡単ではありません。 単一インスタンス個別データベース方式にも課題はあり、1つのインスタンス内のデータベース数とテーブル数がスケールしたことで、マイグレーションにかかる時間の増加などの課題が生じた事例をSmartHR社が紹介しています *12 。今回はそこまでのスケールは不確実であり、懸念には考えていません。また、アプリケーションの特性として、テナントは明確に分離されており、今後は複数インスタンス構成も比較的容易に導入できると考えています。 図6 複数インスタンス構成 最後に 私にはGoogle Cloud と Kubernetes の経験がほとんどなかったのですが、さまざまな選択肢の Pros & Cons やトレードオフを整理して構築を進めていくことは非常に良い経験になりました。 9年目を迎えた弊社の TUNAG では、ありがたいことに導入企業数やユーザー数が着実に増えています。このようなスケールに伴い、今後の中長期的なスケーラブルなアーキテクチャのための取り組みを積極的に行っています。また、マルチプロダクト戦略にも本格的に取り組んでおり、0 → 1でアプリケーションを構築する機会も今後ますます増えていくはずです。 クラウドを中心としたアーキテクチャ構築に興味を持っているエンジニアにとっては、非常にやりがいのある環境だと感じています。少しでも興味を持っていただけたら、ぜひまずはカジュアル面談でお話しできればと思います。 herp.careers 参考 Golding Tod. (2024). Building Multi-Tenant Saas Architectures: Principles, Practices, and Patterns Using AWS . California: O'Reilly Media. (ゴールディング・トッド. 河原 哲也・櫻谷 広人(訳)(2025).マルチテナントSaaSアーキテクチャの構築―原則、ベストプラクティス、AWSアーキテクチャパターン) *1 : AWS における SaaS アプリケーションのテナントルーティング戦略 *2 : SaaS におけるテナントリソースへのリクエストルーティングを JWT を用いて実現する *3 : バニティサブドメインは、SlackやZoomなど広く採用されている。今回のアプリケーションの仕様では、ログイン時にサブドメインを入力するため、記憶しやすいバニティサブドメインを用いた方がユーザーエクスペリエンスは向上する。SmartHR社の スマートフォン向けアプリのログインにサブドメインの入力が必要になりました(03/21更新) のような体験に近い。 *4 : All networking pricing *5 : Cross namespace communication in GKE ingress *6 : About the Gateway API Comparison of Ingress and Gateway *7 : Deploying Gateways Restrictions and limitations *8 : Google Kubernetes Engine 上で SaaS プラットフォームを作成する *9 : Windows Azureエンタープライズアプリケーション開発技法 マルチテナント・アーキテクチャ を参考にした。"データベース"という単語が PostgreSQL で用いられる"データベース"との混同につながる。よって説明の便宜上、参考記事の語彙を、「データベース → インスタンス」、「スキーマ → データベース」に置き換えて本記事では表現をさせていただいた。 *10 : RDBを使わない究極のマルチテナント *11 : activerecord-multi-tenant *12 : SmartHR が定期メンテナンスを始めた理由とやめる理由
アバター
はじめに プロダクト開発部でTUNAGの開発をしている hisa です。最近、花粉の症状が出始めて悩まされています。目のかゆみと戦いながらも、先週EMConf JP 2025に参加してきました。 エンジニアリングマネジメント(EM)は、エンジニアのキャリアの中でも特に難易度が高い領域の一つだと感じています。私はEMではありませんが、「プロダクトに関わるすべての人が幸せになれば」という思いを持ち、そのためには「良いプロダクトを作るには良い組織が必要」と考えています。その延長として、EMについての理解を深めたいと思い、EMConf JP 2025に参加しました。 今回のカンファレンスを通じて、EMという役割の多様性と、その難しさを改めて実感しました。また、EMだけの問題ではなく、エンジニアとしても組織やプロジェクト運営に関わることの大切さを学びました。本記事では、非EMの立場から見たEMの役割や学びについて、特に印象に残ったポイントを紹介します。 エンジニアとしての学び 1. 不確実性との向き合い方 「エンジニアリングは不確実性との戦い」と言われることがありますが、EMにとっても同じであることが分かりました。 カンファレンスでは「フェイルファスト(Fail Fast)」という考え方が強調されていました。特に印象的だったのは、不確実性を無理に排除しようとするのではなく、向き合い、小さな成功体験を積み重ねていくことが重要だという話です。 エンジニアリングにおいても、技術選定や仕様策定の際に「最適解が分からないから決められない」と迷うことは多々あります。しかし、その状態を避けるのではなく、「とりあえず試す」「失敗してもすぐにリカバーできる環境を整える」といったアプローチが大切だと感じました。 2. タスク管理ではなくリスク管理 「プロジェクトマネジメントとはタスクを管理するのではなく、リスクを管理すること」という話がありました。 ソフトウェア開発は目に見えないことが多く、進捗の管理が難しいですが、そもそも「進捗を管理しようとする」こと自体が間違っているのかもしれません。 重要なのは、何がリスクになり得るかを見極め、それを最小化すること。 特に、以下のポイントが印象に残りました。 進捗共有を頻繁に行うこと プロダクトの完成形が見えにくいからこそ、こまめな共有が必要 チームメンバーだけでなく、ステークホルダーにとっても進捗が可視化されている状態を作る タスクよりもリスクを中心に考えること 「このタスクが終わるか?」ではなく、「どこでつまずく可能性があるか?」を考える これはプロジェクトマネージャーだけでなく、エンジニアとしても意識できるポイントだと感じました。 3. 技術的負債とエンジニアリングマネジメント 技術的負債に関する話も多く出てきました。「技術的負債とアーキテクチャは対の存在」という考え方はとても腑に落ちるものでした。技術的負債は見えてしまえば管理できる。逆に言えば、見えていないから管理が難しくなる。 エンジニアとしても、以下のような点を意識することで、EMや組織全体に貢献できるのではないかと感じました。 技術的負債の可視化 負債がどこにあるかを整理し、共有する ADR(Architecture Decision Record)の管理 どんな判断をしたのか記録を残し、振り返りやすくする 非機能要件の見える化 性能・運用コスト・可用性などの指標を数値化する EMは「エンジニアが働きやすい環境を作る」役割ですが、その環境づくりにエンジニア自身が協力することも重要だと感じています。 EMの役割とは? EMの役割について話を聞く中で、「EMとは価値を実現するためになんとかすること」という表現が印象に残りました。 これは単にチームの管理をするのではなく、「必要なことを理解し、それを実現するためにあらゆる手段を講じる」役割だということです。 「なんとかする」とは? 制約のある中で、目標を達成する手段を探す 必要なスキルがなければ、自ら学ぶか、適切な人をアサインする プロダクトの方向性が見えないときに、仮説を立て、検証のサイクルを回す 組織の成長に合わせて、マネジメントの仕組みそのものを変える つまり、EMは「何をすべきか」「どうすれば組織として目標を達成できるか」を考え、障害を取り除く仕事をしていると感じました。 これは、EMだけの話ではなく、エンジニアとしても「自分の仕事をどう価値につなげるか?」を考える上でヒントになる考え方だと思いました。 まとめ 今回のEMConf JP 2025を通じて、エンジニアリングマネジメントの奥深さを学ぶことができました。 EMという役割は「エンジニアが最大限の価値を発揮できる環境を作ること」にあると理解しましたが、そのためにはエンジニア自身も組織の在り方やマネジメントを意識することが重要だと感じました。 特に印象に残った学びは以下の3点です。 不確実性に向き合い、小さな成功体験を積み重ねること タスク管理ではなくリスク管理を重視すること EMだけでなく、エンジニア自身も組織の改善に関わること 良いプロダクトを作るためには、良い組織が必要。 そのためにEMが果たす役割は大きいですが、エンジニアとしても「組織やチームを良くするためにできることは何か?」を考えていきたいと思いました。 さいごに BuySell Technologiesさんのブースでガチャガチャがあり、硬貨が当たりました。 とても貴重そうなので大切にとっておきます✌️ BuySell Technologiesさんのブース スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers
アバター
TUNAGのプロダクト開発チームでiOSアプリを開発している おしん です。 SwiftUIの標準コンポーネントである List を使う機会があったのですが、List を使ってデザイン通りに画面を実装することは予想以上に困難でした。 このブログでは、Listのデフォルトの挙動と適切な対処法について紹介します。 List とは UIKitの UITableView に相当するSwiftUIのコンポーネントで、縦方向のスクロール可能なリストを作成できます。 Listを使用することで、データ配列を自動的にレイアウトし、パフォーマンスが最適化されたスクロール可能なUIを構築できます。 以下のコードでは、 items の配列をリストに変換し、各要素を Text で表示しています。 struct ContentView : View { let items = [ "Pacific" , "Atlantic" , "Indian" , "Southern" , "Arctic" ] var body : some View { List(items, id : \. self ) { item in Text(item) } } } Listの使い所 無限スクロールの実装が必要な画面では、配列の要素の(個数 - 1)番目が画面に表示されたら、次の要素を配列の末尾に足すという方法を取ることが多いと思います。 その際、(個数 - 1)番目の要素のViewの .onAppear を適切に制御する必要がありますが、 ScrollView + LazyVStack を用いた実装では、要素追加時の .onAppear の発火タイミングの調整が難く、実用的ではありません。 そのような場合においてはScrollView + LazyVStack ではなく、子要素の.onAppearを適切にハンドリングできるList を使うことが推奨されます。 List の何が大変か 高いパフォーマンスを発揮する List は便利なコンポーネントですが、Listのデフォルトの挙動を調整する際に、以下のような難しさがありました。 行・セクションの余白やセパレータの扱い List 内に埋め込んだボタンが意図しない挙動をする それぞれの課題と対処法を紹介します。 行・セクションの余白調整 デフォルトでは以下のように余白やセパレータが適用されているため、デザインに合わせて調整が必要です。 出典: https://developer.apple.com/documentation/swiftui/list List { Text( "Pacific" ) .listRowSeparator(.hidden) // セパレータを非表示にする .listRowInsets(EdgeInsets()) // 行の余白をなくす(四隅のpaddingを0にする) } .listStyle(.plain) // Listのデフォルトのスタイルを変更 セクションの余白については、iOS15 以降では行の余白を消す API が提供されていますが、セクションの余白を消す API は iOS17 以降でしか利用できません。 そのため、以下のように inset を余白分だけマイナス値で相殺することで回避しました。 if #available(iOS 17.0 , * ) { List { Text( "Pacific" ) } .listSectionSpacing(.leastNonzeroMagnitude) // iOS17以降でのみ使用可 } else { List { Text( "Pacific" ) .listRowInsets(EdgeInsets(top : - 20 , leading : 0 , bottom : 0 , trailing : 0 )) // セクションの余白を相殺 } } ボタンが意図しない挙動をする問題 List ではデフォルトでスワイプアクションやコンテキストメニューのようなボタンが用意されています。 そのため、行に対して追加でボタンを配置すると List 側のボタンと競合してしまうことがありました。 List のデフォルトのアクションを無効化するか、明示的にカスタムボタンの動作を定義することで意図しない動作を防ぎました。 List { Button(action : {}) { Text( "Pacific" ) } } .buttonStyle(.plain) // rowのデフォルトのタップアクションを無効にする ボタンが反応しなくなる問題 1行に複数のボタンを埋め込むと、特定のボタンがタップに反応しなくなることがありました。 Rectangle を shape に設定することで回避しました。 List { HStack { Button(action : {}) { Text( "button1" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 Button(action : {}) { Text( "button2" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 } } .buttonStyle(.plain) 全体像 以上を踏まえ、Listのデフォルトの見た目を最大限抑えた場合の全体像がこちらになります。 // セクション間の隙間の調整が必要な場合は // iOS 17以上 → `listSectionSpacing` // iOS 17未満 → `listRowInsets`の当て方を調整 List { Group { HStack(spacing : 0 ) { Button(action : {}) { Text( "button1" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 Button(action : {}) { Text( "button2" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 } let items = [ "Pacific" , "Atlantic" , "Indian" , "Southern" , "Arctic" ] ForEach(items, id : \. self ) { item in Text(item) } } .listRowBackground(Color.clear) // 背景透過 .listRowSeparator(.hidden) // セパレータを非表示にする .listRowInsets(EdgeInsets()) // 行の余白をなくす(四隅のpaddingを0にする) } .listStyle(.plain) // Listのデフォルトのスタイルを変更 .buttonStyle(.plain) // rowのデフォルトのタップアクションを無効にする .environment(\.defaultMinListRowHeight, .leastNonzeroMagnitude) // rowのデフォルトの高さを0にする プレビュー まとめ 無限スクロールを実現するために List を採用した結果、List のデフォルトの挙動について深く理解する機会となりました。 SwiftUI の List は便利ですが、デフォルトの挙動が多く、その挙動を最小限にするには多くのモディファイアが必要であるとともに、そのデフォルトの挙動を十分に理解する必要があると感じました。 本ブログが List を使う際の参考になれば幸いです。 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! herp.careers
アバター