Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

エンジニアの成長に技術力は必要条件であって十分条件ではない - 文系新卒エンジニアが大規模開発から得た技術以外の3つの成長

※この記事は、2024 Speee Advent Calendar 23日目の記事です。 昨日の記事はこちら

tech.speee.jp


はじめに

こんにちは、SpeeeのDX事業部でHousiiというサービスのアプリケーション開発をしている24新卒の北田です。大学では法学部で文系の出身でしたが、現在はReactとRailsを使用したフルスタック開発に携わっています。

入社から半年が経ったあたりで、私はサービス開始以来最大規模の新規開発のリードという機会を任されることになりました。このプロジェクトを通じて、私は「エンジニアの成長に必要なのは技術力だけではない」ということを強く実感しました。

そこで、この記事では、以下の3つの観点から、エンジニアの技術以外の成長について共有させていただきたいと思っています。

  • 事業視点での判断力:機能を「作る」前に「判断する」ことの重要性
  • 技術的な判断力と実装以外の視点:パフォーマンスと設計の両立、チーム全体での最適化
  • プロジェクトマネジメントとコミュニケーション:計画と現実のギャップへの対応

これからエンジニアを目指す方に、技術力以外の成長の重要性を感じていただければ幸いです。

エンジニアとしての土台作り

プログラミングとの出会いから入社まで

まず初めに、入社前の段階で私がどの程度のスキルレベルだったのかをお伝えできればと思います。 私のエンジニアとしてのキャリアは、大学1年生の終わりにプログラミングサークルに入ったことから始まりました。最初の1年間は主にDjangoを使用したバックエンド開発の学習に費やしました。正直なところ、学習しているときはプログラミングが自分に合っているのか不安を感じていました。

しかし、転機となったのは大学2年生の12月に参加したハッカソンでした。そこでチーム開発の醍醐味に触れ、エンジニアという職種に強く惹かれるようになりました。その後、2年間の実務経験を経て、以下のようなスキルセットを持って入社することになりました。

入社時のスキルセット

  • バックエンド開発(Python/Django): 3年の経験
  • 実務開発経験:2年
  • フロントエンド開発:ほぼ未経験
  • TypeScript/Ruby:ほぼ未経験
  • CSの知識:ほぼなし

技術以外の重要性に気づくまでのプロセス

入社から約半年の間、私はエンジニアとしての成長に必要なものは「技術力」だと思い込んでいました。しかし、徐々に責任範囲が広がっていく中で、技術以外の要素の重要性に気づかされていきました。以下は、その気づきのプロセスです。

基礎スキル習得期(入社〜2ヶ月目)

この期間は、実務で必要な基本的な開発スキルの習得に必死でした。今思えば技術力の向上だけに囚われていた時期です:

  • 簡単なイシューから取り組み、実装経験を積む
  • コードレビューでの指摘を受けながら、実装力の向上を目指す
  • フロントエンド(React)とバックエンド(Rails)の基本的な実装スキルの習得

視野の広がり期(3-4ヶ月目)

この時期、私は技術的な実装だけでなく、設計の重要性に気づき始めました。しかし、今思えばまだまだ技術的な視点に留まっていました:

  • 2週間規模の開発での設計経験を通じて、実装前の技術的な設計の重要性を学ぶ
  • 機能要件から技術要件への落とし込み方、実装方針の立て方を経験
  • 保守性と拡張性を意識したコード設計の必要性への気づき

チーム視点の醸成期(5-6ヶ月目)

個人の開発力が一定の水準に達してきたことで、チームとしての開発の重要性に目を向けられるようになりました:

  • 朝会でのコミュニケーションを通じて、個人の作業進捗だけでなく、チーム全体のゴール達成への意識が芽生える
  • コードレビューにおいて、単なる技術的な指摘だけでなく、チームでの保守性を考慮した建設的な提案ができるように
  • 個人の開発速度だけでなく、チーム全体での開発効率を考慮した実装の重要性への気づき

総合的な判断力の必要性に気づく時期(7ヶ月目以降)

サービス開始以来最大規模の新規開発を任されたことで、エンジニアには技術力以外の多くの能力が求められることを痛感しました:

  • 技術的な実現可能性だけでなく、事業的な価値やコストを含めた総合的な判断の必要性
  • チームメンバーとの協働において、技術的な議論以上にお互いの価値観や考えを理解することの重要性
  • プロジェクトの成功には、個々の実装力よりもチーム全体のベクトル合わせが重要であることへの気づき

技術力以外の3つの重要な学び

ここからは、いよいよ本題である私がプロジェクトをリードする中で学んだ「技術力以外の3つの重要な要素」についてお伝えします。

具体的には、

  • 事業視点での判断力
  • 技術的な判断力と実装以外の視点
  • プロジェクトマネジメントとコミュニケーション

です。それぞれの要素について、私が直面した課題と、その解決プロセスを通じて得た学びを共有させていただきたいと思います。

1. 事業視点での判断力

エンジニアは「コードを書く人」から「ビジネスの成功に貢献できる判断ができる人」へと成長する必要があります。これは、単なる技術的な実装以上に、事業としての価値判断が求められるということです。

このような判断力の重要性を、私は以下のような経験を通じて学びました。

直面した課題

  • 私が、プロジェクトをリードする上で最初に直面した課題は、エンジニアとしての技術的な実装だけでなく、事業視点での機能の価値判断という、これまでにない難しさでした。
  • 単に「機能を作って欲しいから作る」のではなく、その機能が本当に価値のあるものなのか、をエンジニアの視点を持って考えることが求められました。
  • 特に、収益性とコストのバランス、技術的な実現可能性の検証など、これまでの業務では経験したことのない判断が必要でした。

解決のためのアプローチ

  1. 事業的な価値の検証

    • ビジネスサイドと議論を重ね、機能の意味・ビジネス背景と得たいゴールを理解
    • 事業フェーズにおける重要性を評価
    • 想定される事業への影響度の分析

  2. コストとリターンの評価

    • 外部APIの利用コストを試算し、収益性を検討
    • 開発工数とビジネスインパクトのバランスを評価

  3. 工数出しと技術的な実現可能性の検証

    • 全体の機能の見積もり出し
    • 不確実な要素の技術検証の実施(スパイク)
    • 非機能要件を満たせる設計の検討
    • 想定される最大限のデータ量での動作確認

得られた学び

機能を作った後でコスト的・技術的な問題が発覚することは最も避けるべき事態です。事業を共に作る一員として、以下の順序で検証を進めることが重要だと学びました。

  1. まず事業的な価値の確認を行う
  2. 次にコストとリターンの評価で実現性を判断
  3. 最後に技術的な実現可能性の詳細な検証を実施

1と2はとにかく早い段階で詰めていくことが何よりも大切です。2に関しては、そもそも収益よりもコストのほうがかかるのであれば、事業としては成り立たなくなるので最初の時点でやれないという判断になります。機能を作った後にコスト的に成り立たないことがわかった状態は最も避けたいので、早い段階で調査・見積もりを行って潰すべき箇所です。

2で収益見込みがあるのであれば、次は3を実施していきます。工数があまりにもかかるのであれば事業的に別の機能を作った方が良いという判断になるかもしれません。そのため、ここも最初の段階で粗くても全体開発工数を早い段階で出していく必要があります。

出した工数に対して事業としてやる価値があるのかどうかを話し合います。やる価値があるのであれば、そこから不確実な技術検証・非機能要件を決めて実現可能性を探っていきます。実現可能性があることがわかったら、ようやく開発をしていく段階に持っていけます。

2. 技術的な判断力と実装以外の視点

技術的な課題解決において重要なのは、個人の実装力だけではありません。パフォーマンスや設計の問題は、チーム全体での最適な解決策を見出すことで初めて本質的な改善が可能になります。そして、その過程では純粋な技術的な視点だけでなく、ユーザー体験やチームの開発効率など、より広い視点での判断が必要となります。

以下は、この考えに至った具体的な経験です。

直面した課題

フロントエンドとバックエンドの両面で、パフォーマンスや設計に関する重要な課題が次々と発生しました。事前の技術検証をすることで、パフォーマンス部分はある程度、事前に設計・対応方針ができていましたが、実装する中で初めて見えてきた箇所も当然出てきました。

フロントエンド面での課題:

  • 大量データを扱う画面での表示の遅さ
  • 不要な再レンダリングによるパフォーマンス低下
  • 予期せぬ画面クラッシュの対応

バックエンド面での課題:

  • GraphQLでのN+1問題によるレスポンス低下
  • APIコストを下げるための複雑な条件処理
  • 非同期処理の必要性

解決のためのアプローチ

フロントエンドでの対応:

  • キャッシュを用いて事前に呼んでおくようにする
  • ステート管理を最小限に抑えて再レンダリング数を防止
  • メモ化による計算コストの削減
  • レイヤー、リフロー、リペインティングを考慮したCSSの設計

バックエンドでの対応:

  • Promiseによる遅延実行処理の理解をし、複数モデルを組み合わせてもN+1が起きないようにGraphQL内でJOINを繋げていけるようにする
  • 複雑性をもたらす条件を把握して、条件を日本語で洗い出してコード・テストケースに落とし込む
  • 非同期処理の活用とジョブキューの設計

得られた学び

通常の開発でも当たり前のことを、より慎重に考える必要性を学びました。

  • ユーザーがどのように使うのかを想定した上で通常操作内のパフォーマンス基準点の理解が必要
  • パフォーマンス問題は早期に発見し対処することが重要
  • フロントエンド・バックエンド両方の視点での最適化が必要
  • 実装前の設計の重要性と、設計変更の影響範囲の見極め

特に最後の事前の設計に関しては、「一歩引いた視線」を持って実装することが重要です。

具体的には、コードを書く前に

  • 「この実装は将来的な拡張性を考慮できているか?」
  • 「この設計は他のエンジニアが見ても理解しやすいものになっているか?」
  • データの流れから親子関係を捉え、「どちらに責務を持たせるべきなのか?」

といった質問を自分に投げかけながら実装を進めていくことです。 私自身、現在はこのような思考を意識的に行うよう心がけています。早い段階でこの習慣が身につけば、コードの品質が大きく向上するはずです。

3. プロジェクトマネジメントとコミュニケーション

プロジェクトの成否を分けるのは、実は技術力以上にコミュニケーション能力です。チームメンバーと効果的に対話し、互いの考えや制約を理解し合う。そして、その理解をもとにプロジェクト全体を円滑に進めていく。この能力は、エンジニアの成長においてとても重要な要素でした。

この重要性を、私は以下のような経験を通じて痛感しました。

直面した課題

  1. 工数見積もりのズレ

    • 大規模プロジェクトを任され、最初に痛感したのは工数見積もりの難しさでした。当初、機能実装の工数を1ヶ月半と見積もっていた部分が、実際には2ヶ月以上かかってしまいました。「なぜこんなにズレてしまったんだろう」と悩む中で気付いたのは、不確実な要素に対する私の甘い認識でした。
    • 「実装しながら考えれば何とかなるだろう」という安易な考えで進めてしまい、途中で必要になった設計の見直しを適切にイシュー化できずに、ただただ実装を進めることで精一杯になっていました。

  2. エンジニア以外のチームメンバーとの認識齟齬

    • デザイナーやプランナーとのコミュニケーションにおいて大きな壁にぶつかりました。お互いの認識齟齬により、実装途中に要件の見直しに伴う修正やデザイン待ちが発生する事態が起きました。 結果として、自分自身の実装の手戻りだけでなく、他のエンジニアの作業にも影響を与えてしまいました。

解決のためのアプローチ

  1. 工数管理の改善

    • 苦しい状況の中、チームメンバーから重要なアドバイスをもらいました。「不確実な要素が実装して初めて出てくること自体は仕方のないことだ。しかし、そこで重要なのは、きちんと計画を引き直して、追加で必要な対応をまとめ直すこと」。また、「そもそも適切なゴールを設定せずに優先順位判断がうまくできていないことが、問題をすぐに対処できない状態を生み出している」ということを気づかせてくれました。
    • このアドバイスを受けて、毎日チームの進捗共有会を行う朝会の準備をしっかりと行うようにしました。取り組むイシューを優先順位順に並べ、上から順番に進めていくための対策・準備を朝会の前に必ず準備する。自分がプロジェクトを主導しているため、責任を持ってアサイン割り振りを行い、そのようなアサインをしていることの説明責任を果たせるようにすることを心がけました。
    • その中で重要だった箇所は、最も達成したいものをゴールとしておくことでした。他のイシューを落としてでも優先して達成したいものをゴールとしておくことで、仮に予期してない箇所での問題が起きて、差し込み対応が必要になった場合であっても、再度大幅に計画を練り直すことなく、ゴールをいかに早く達成できるかを考えることを軸にして考えられるようになりました。
    • 結果として、着実にゴールを達成していける見立てを作ることができ、自信を持ってそれぞれが自分が担当するイシューをこなしていくことに集中していけることができたと思います。

  2. エンジニア以外のチームメンバーとの適切なコミュニケーション

    • デザイナーやプランナーとのコミュニケーションを見直しました。デザイナー・プランナーの譲れない観点とエンジニアとして調整可能な部分を早期に確認し、実装の方向性を合意する。 その際、重要なのは背景理解を怠らないことです。どうしてそのように考えているのか、そこにはプロダクトとしてユーザーに届けたい価値の考えが必ず存在しています。そこをきちんとお互いに認識のすり合わせを行うことで、すれ違いが減り、手戻りを防ぐことにつながります。
    • また、依頼をする際に、期日を相手に投げるのではなく、こちらでしっかりと状況を把握した上で「いつまでに」「どういう理由で」必要なのかを明確に伝えることの重要性を学びました。 当然のことですが、相手にも相手の仕事があります。相手の状況を考慮した上で、対応しやすい形で依頼を行う、つまり「いつまでに何をどうしてほしいのか」が明確に伝わる状態で依頼することが、プロジェクトを円滑に進める上で極めて重要だと実感しました。

得られた学び

この経験から、最初に立てた計画は多くの要素・要因によってズレることの方が多いので、計画そのものを緻密に立てていく事よりも、重要なのは、計画からのズレを早期に発見し、どう軌道修正するかの判断と準備だと感じました。

また、プロジェクトマネジメントにおける「コミュニケーション」の重要性も、身をもって学びました。エンジニアとして「技術的に正しい実装」を追求することは大切ですが、それ以上に「チームとして最適な解決策を見つけること」が重要だと気づきました。チームメンバーと早期に認識を合わせ、お互いの制約や要望・考えの背景を理解し合うことで、後からの大きな手戻りを防ぐことができます。

まとめ:エンジニアとしての総合的な成長とそのために必要な要素

プロジェクトリードの経験を通じて、エンジニアの成長において技術力は必要条件ではあるものの、十分条件ではないことを学びました。真の成長は、以下の3つの要素のバランスの上に成り立っているのではないかと感じています。

  1. 事業を理解し判断できる力:単なる実装者ではなく、プロダクトの価値を創造する一員として
  2. 技術と人の両方を見据えた視点:技術的な正しさだけでなく、チーム全体での最適解を見出す力
  3. チームでの成功を導くコミュニケーション力:異なる役割や視点を持つメンバーと共に、より良いものを作り上げる力

これらの力を身につけていく過程で、私は大きな不安や困難に直面することも多くありました。しかし、振り返ってみると、その一つ一つが確実に自身の成長につながっていたと感じています。

特に重要だったのは、次のようなマインドと、それを活かせる環境です:

  • 段階的な責任の拡大を受け入れ、その中で着実にスキルを積み上げていく姿勢
  • 失敗を恐れないチャレンジ精神と、その失敗から学ぶ謙虚さ
  • 周囲のサポートを素直に受け入れ、それを自身の成長の糧にする前向きさ

技術力を磨くことは確かに重要な要素です。ただ、私自身の経験を通じて、それ以外にも大切な要素があることを実感しました。事業やチームの中で価値を生み出すには、技術力とともに、事業への理解やコミュニケーション力も必要不可欠だと感じています。

この記事で紹介した経験と知見が、皆さんのキャリアプランニングの参考になれば幸いです。

最後に

Speeeではときに失敗をしながらも、各メンバーがサービスの改善やその先にあるミッションの実現に日々向き合っています。 Speeeのエンジニアの事業への向き合い方について共感していただけた方、Speeeでは一緒にサービス開発を推進してくれる仲間を募集しているので、ぜひ以下のフォームからお申し込みください。

新卒の方はこちらより本選考に申し込みが可能です

キャリア採用の方はこちらのFormよりカジュアル面談も気軽にお申し込みいただけます

Speeeでは様々なポジションで募集中なので「どんなポジションがあるの?」と気になってくれてた方は、こちらをチェックしてみてください。

もちろんオープンポジション的に上記に限らず積極採用中です!