Tsuyoshin blog

所属団体とは関係なく、個人的なblog

PHP Way #1 勉強会に参加して自らのプロダクトでPHPを選んだ経緯を振り返る

参加した勉強会

base.connpass.com

はじめに

ようやく自分自身にエンジニアとしての精神的な余裕ができてきたのでコミュニティ活動を再開するんだ!と思ったけど

PHPでカジュアルに参加できる勉強会とか少ないなーと感じてた。

そんな中、いつものように会社でtwitterを眺めてたらこの勉強会を発見し、近いし参加させてもらいました。

本題

一応自分もスタートアップからサービスを開発をしてきました。当然最初の技術選定やらはしていて、そこでメイン言語をPHPにした経緯や当時の狙いみたいなところを振り返ってみようと思います

序章

2013年5月1日に今の所属している会社は設立され、その年の5月下旬か6月ぐらいにjoinした。

株式会社マクアケ

そこの会社で立ち上げるサービスに関して決められていたのは

  1. その年の6月中にサービスのティザーサイトをオープンさせる。
  2. その2ヵ月後ぐらいにサービスオープンさせるぞ!!😱...いけるのかぁ😰

その時いたエンジニアは私ともう一人でトータル2人。あとは業務委託として数名きてもらって一気に作るという感じだった

サービス自体は当時全く認知度が無かったクラウドファンディング。 まぁ技術的な視点でみると仕組みはEC+アルファのような感じでした

提供デバイスはとりあえずPCのブラウザ版をターゲット。のちにすぐにスマホのブラウザ版もターゲット

まぁよくあるwebですね

www.makuake.com

↑このサービスの立ち上げでした

大枠を決めた

まずはインフラはその頃からAWSが出始めてきてグループ社内でも使われ始めたのもあってAWSで良いんじゃないかという感じになりました。最初からインフラエンジニアというポジションで誰か来てもらう余裕なんて無いし

AWSはこれはこれで中々大変でしたが、今回はちょっと本題からずれるので置いておく

サーバサイドアプリケーション側のメイン言語はLL言語ってだけ決めた。webですし、何よりも改善スピードを重視したいという事もあった

会社には新規事業をどんどん立ち上げる文化がありますが、同時に決められた期間内に黒字にならないとクローズというルールがあります。 自分も実際にクローズを経験しました😨

LLの中でどれにしようか悩んだ

一応言語のその当時の印象やら評価をざっくりした

振り返り、まとめる下記のような感じだったと思います

言語 振り返りコメント
perl 今更perlで作るのもなぁー。そもそもperlで人が集まるのかなぁ。コードの書き方が色々ありすぎて統一感なくなりそう
python たぶんDjangoになるだろうなぁー。個人的にはこの組み合わせは好きだし良いけど、人材確保無理じゃない?めっちゃ苦労しそう。今でさえデータ分析系が流行っているのでpython周辺のコードをいじるエンジニアは増えているようだけど
ruby 当時2.0系に上がったぐらいでまだそこまでのスピードがない印象。でもrailsが盛り上がりつつあるのか?!
PHP 5.4 or 5.3あたりで、当時ソーシャルゲームが流行り始めて、PHPで作っていく組織が多くあった。PHPerいっぱいの印象

最終的に

結局は多くのクローズする事業を目の当たりにしてきて(当事者になるとツライです)、期限内に黒字化達成をする為に爆速で開発ができる事を最優先に考えた

そこから逆算すると自分たちのスキルセットと外部でお願いするエンジニアの確保のしやすさが重要。

自分含め2人いた創業エンジニアの今までのLL言語の経験でいうとperl,python,PHPだった。自分は直近python。もうひとりのエンジニアはPHPだった。

そうするとpython or PHP

それに外部からのエンジニアの確保のしやすさを考えると(当時だと) -> PHPですね🎉🎉🎉

フレームワーク選び

これは個人的な思考もありますが、軽量なフレームワークがいい!というのがありました。

その観点でいうと当時だとCodeIgniter

だけど、ちょうどその頃ライセンス問題が話題になっていて(のちに解決されていたのですが)、そのあたりからFuelPHPがこれから来るのではないかと信じて思い切って選択しました

その後、来たかどうかは...

まとめ1

  • 実はこの検討する時間が2、3日に考えて決めたんだよなー...
    • まぁちょっとあまりにも時間がなさすぎるというか、無理があるすぎると言うか...これがスタートアップなんでしょうかね...
  • PHPを選択した背景を4年前を思い出しながら書いたけど、4年前ってまだ20代じゃないか。色々知識が足らず未熟な選択も多分にあったと思う
  • ただ、時間は流れ、適材適所で言語を複数使いながらサービスを作り上げるのは今の主流なので今ではPHPだけではない
  • コードは常に書き換わるものなのでそういった循環のサイクルを回す事のが重要な気がしている
  • もちろんこれからもPHPも書くし、用途に合わせて別の言語も書くし、継続してアウトプットして少しでも良い情報を還元できればと思いっている

まとめ2

自分で言うのもなんですが、サービス立ち上げから無事に4年すぎ、そこそこまで立ち上がったと思うので当時の技術選択を用いてサービスの立ち上げは成功したんじゃなかろうかと思っています。🎉🎉🎉

以上、php wayを機に得た振り返り機会でした

おまけ

  • 勉強会の最後のパネルディスカッションでどういったエンジニアを採用したいかという話があった。
  • 自分も同意ですが、サービスに対してコミットしてくれて、サービスの成長・改善を第一に考えてくれるエンジニアを採用したい(もちろんプラスで技術力高い人)と。
  • でも現実問題としてサービスの成長やアクセルを踏み込むべきタイミングは待ってくれなくて、いつまでにどのくらいのエンジニアを増やして開発を加速させなきゃいけないというような時はある。理想ばかり言ってられなくなる
  • 妥協ではないけど、どこかで区切りというかラインを下げつつ事を先に進めなきゃいけないんだよなぁー。という現実とのギャップの苦しみはないですか?的な質問を懇親会でしたかったけど、ちょっと本業で急遽予定が入ってしまい、渋々先に上がってしまった

2017年の振り返り

はじめに

やっぱ年末になったので今年一年どんな開発をしたのか振り返っておきたいと思います。もちろん自分一人だけでは何もできないのでチームの成果でもありますが、自分が主となって開発してきた部分を中心にまとめてみようと思います

ちなみに

うちはメインのレポジトリに関してはリリースノートなるものを作っております。簡単にリリースしたプルリクを日付ごとにmarkdown形式に並べている(リンクさせています)

これを元に振り返って見ようかと思います

例(抜粋)

こんか感じのリリースノート f:id:tsuyoshi_nakamura:20171206021535p:plain

1-2月

ガイアのテレビ砲に備え、キャッシュ部分を増やしたり、expireを伸ばしたりして備えていた

blog.makuake.com

結局ここでの結果がシステム的にはあまり良くなくて根本的な見直しを...😱 年始早々ツライ

個人的にはだいぶショックがあり、数日は仕事していなかった記憶があります。今年はここに向き合うんだろなーと感じた1月でした。

ここでの改善項目は大きくは下記でした

  • とにかくPHPのアプリケーションのパフォーマンスが悪すぎるので見直す
    • サーバを増やしたり、スケールアップ、キャッシュの見直し等々のインフラ的な対策ももちろんあるけど
  • DBの見直し

ビジネス的には割と地味な戦いが続くな〜という感じだけど、エンジニアの最も重要な保全活動に力を注ぐ感じになりました

3~5月

1. DBのAurora移行

developers.cyberagent.co.jp

詳細は上記の記事に書いてありますが、不要なレコードを削除したり、drop tableして軽量化を図りつつ、最小のダウンタイムで移行した!!

自分は主にサポート業務になりました

副次的によかったのは2つ

1-1. AuroraのReaderが気軽に作れるのでre:dashを導入出来た事

tsuyoshi-nakamura.hatenablog.com

BIツール系も試せたのでチームにとっても良かったのではないかと

Googleデータスタジオを使って見てBIツールについて考えた - Tsuyoshin blog

1-2. Fluent,Kibanaで500エラーログ、slowクエリの可視化

問題が見える化されると改善のスピードは格段にあがる

2. PHPパフォーマンスチューニング

そもそももっとパフォーマンス改善できるよねという感じでまずは調査からして、ボトルネック見つけて、排除して、改善した

tsuyoshi-nakamura.hatenablog.com

色々ありました

  • preg_matchからstrposへ移行したり
  • UserAgent判定をそもそもNginxへ移行したり

3. キャッシュ系の戦略

このへんで色々と考えたり、検証したりしたけど結局productionへの導入まではしませんでした

6~8月

Newrelicの活用がもっと進みAWS SDK経由のAWSAPIアクセスが遅い事に気づいて対応を進めた。外部URLのAPIコールも結局は同様で外部依存になっているところのパフォーマンスが落ちていた。

またImageMagicをphp経由で利用している箇所が比較的パフォーマンスが悪かった (そりゃそう)

AWSへのAPIアクセスを必要最低限にする工夫と画像処理(サムネイル生成とか)の課題を取り組む事になった

1. 外部APIコールのアクセスを最小限へ

とにかくDBやキャッシュを大いに活用してS3へのアクセスは最小限にした。

仕方なく外部のAPIをコールするときはGuzzleで並列リクエスト等の工夫をした

GitHub - guzzle/guzzle: Guzzle, an extensible PHP HTTP client

2. 画像のサムネイル対応

当初、Lambda + node.jsのGraphicsMagicksmall,middle,largeサイズでサムネイル生成をして、CloudFront経由で各画面で最適な画像を選択して使おうとしてた。

でも、また運用タスク増えるなぁー

と色々と画像サムネイルソリューション探ってました

結局最後は、CAグループ内に存在したas Service を活用する事で運用負荷下げながら解決していった

この課題の対象箇所は本当にいたるところにあってトータルで120箇所ぐらいあってとにかくプルリク作りまくった。ここだけで軽く90ちかくプルリクを作ったんじゃなかろうか😅

9-10月

新規でiosアプリを開発が動き始めた

blog.makuake.com

developers.cyberagent.co.jp

自分としては新規メンバーが来てくれるまでGoでAPIの基礎の走りぐらいを作ったにすぎず、ネイティブチームが頑張っておられた!!

レビューアの役割も少しさせてもらった。関連するプログラムのところだけですけど

限られた時間の中でよくリリースできたなーと基本外から眺めてました。

初めてブラウザのチームとネイティブのチームが別れた開発部隊となった

11-12月

よりあゆみを進めようとphp7化に向けてphanを活用して互換性チェックや少しでも不具合のリスクを減らす為にリファクタを繰り返した

tsuyoshi-nakamura.hatenablog.com

ImageMagicの撲滅

  • 少しでもサーバのプロビジョニングを楽にしたい

  • 画像のサムネイル類は外部サービスで完結するようにした

という理由から不要になったImageMagicを使っている箇所をリファクタした。ここも中々のボリュームで15プルリクぐらいつくった😅

時系列には無い細かいところでいうと

この辺は新しく入ってもらったエンジニアに色々と提案いただいて導入出来た事です

1. 開発環境の改善は結構ある

  • database migrationの整備
  • factory、facker導入したり
  • mockテスト導入したり
  • unit テストの時間が短縮したり
  • xmlのfixtureを撲滅してもらったり
  • gulp+webpackをwebpackに統一したり

2. vendor配下に独自ライブラリ

もともとto Cに提供していたメインレポジトリとは別に運用側で使う画面のレポジトリは分けて開発してきた(DBは当然同じ)

当然、同じようなロジックを両方のレポジトリに書くざるおえない場面が増えてきて、中々ツラくなってきた。そこで両方で使えるライブラリのレポジトリを作り、composerでインストールして両方で同じロジックのメソッドを使えるようになってコードがドライになった

その他

  • もはやずっとだけど、ほぼ毎日のリリースマネージメントしてるのでなんだかんだ1日1時間程度はこれに消費してたな
    • 一応STGでの最終手動確認してのリリースボタンをポチ
    • マイグレーションが必要なら実行したり
    • プルリク同士のdependencyがある場合にはちゃんと考慮してリリースしたり
  • システム自体は常に稼働していて、様々な施策が行われている。もちろん不具合も出れば、トラブルシューティングのタスクも存在する。
    • こいつらを対応しながらの作業はなかなかハードだった😅

最後に

  • つらつらと書きたものを眺めているとやはりパフォーマンス改善に多くの時間を使ったなーと感じました
  • 今年のメインレポジトリに約704個のプルリクがmergeされ、shipされた。そのうち約231が自分が起票のプルリクだった。
    • その231のうち半分はパフォーマンスチューニング系のプルリクとなる計算になる(ざっくり)
    • 感覚値とあってる
  • アプリケーションサーバのレスポンスを1年間でaverageでみて見ると下記のグラフになった f:id:tsuyoshi_nakamura:20171207005427p:plain
    • こう見るとめっちゃ改善したなぁーと思う
    • LBのレイテンシーの数値も改善していたので間違いなくユーザにも改善が届けられたと思われる
    • 実は事業的にもCVRが改善したりしたので確実に積み上がる仕事だったのではないかと思っています

来年に向けて

  • 今年の後半ぐらいからは自分はよりコードにコミットできる体制になってきて良く感じている
    • 我ながら立ち上げからコーディングとは関係ない仕事を良くやってきたなと感じている😓
  • 来年はよりコードでプロダクトに良い影響を与えて行きたい
  • より技術的にコミットしていき、今まで控えていたコミュニティ活動も増やして還元して行きたいです💪🏽

phpunitの`@runInSeparateProcess`,`@preserveGlobalState`利用時の注意点

概要

phpでアプリケーションを書いていて、当然unit testも書いています。

unit testを書いている中でmockが必要なパターンが出てくると思います。

その際にとても有名なmockeryを使っています

github.com

んで、mockeryを色々と使ってると@runInSeparateProcess,@preserveGlobalStateが必要になることが多くあります

@runInSeparateProcess

https://phpunit.de/manual/current/ja/appendixes.annotations.html#appendixes.annotations.runInSeparateProcess

@preserveGlobalState

https://phpunit.de/manual/current/ja/appendixes.annotations.html#appendixes.annotations.preserveGlobalState

正確な情報は上記のリンク先にお任せして、要は別のプロセスにしてグローバル参照させない設定という感じですね。

ぶち当たった課題

別プロセスで稼働するということはtestの中でsetUpBeforeClass,tearDownAfterClassを設定していた時に予期せぬタイミングで実行されるという...

具体的に

echoを仕込んで実際に動かしながら見てみる

テスト対象のクラス

a.php

<?php
namespace StaticMethods;

class StaticMethods
{
    public static function func()
    {
        return "this is static method. \n";
    }
}

テストコード test.php

<?php

namespace Tests;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use StaticMethods\StaticMethods;


/**
 * @group Test
 */
class Test extends TestCase
{

    public static function setUpBeforeClass()
    {
        parent::setUpBeforeClass();
        echo 'setUpBeforeClass'."\n";
    }

    public static function tearDownAfterClass()
    {
        parent::tearDownAfterClass();
        echo 'tearDownAfterClass'."\n";

    }
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function test_a()
    {
        $mock = m::mock('overload:' . StaticMethods::class);
        $mock->shouldReceive('func')->andReturn('is this static method ?');
        echo(StaticMethods::func()."\n");
    }
    
    public function test_b()
    {
        echo(StaticMethods::func()."\n");
    }
}

本体予想していたechoの期待値は

  1. setUpBeforeClass ->
  2. is this static method ? -> test_aのecho
  3. this is static method. -> test_bのecho
  4. tearDownAfterClass ->

実際のechoの期待値は

  1. setUpBeforeClass -> test_aの設定の別プロセス or もともとの setUpBeforeClass
  2. setUpBeforeClass -> test_aの設定の別プロセス or もともとの setUpBeforeClass
  3. is this static method ? -> test_aのecho
  4. tearDownAfterClass -> test_aの設定の別プロセス or もともとの tearDownAfterClass
  5. this is static method. -> test_bのecho
  6. tearDownAfterClass -> test_aの設定の別プロセス or もともとの tearDownAfterClass

この結果何が問題になるか

tearDownAfterClassとはテストケースの最後に実行されるメソッドです。それが、まだテストが実行中にも関わらず実行されてしまう...😨

この現象でちょっとハマりました

回避方法

何通りかあると思う

  1. そもそも影響しないようにrunInSeparateProcessの設定があるテストは別に切り出す
  2. tearDownAfterClassを諦めてtearDownを使う
    • テストケースが多い場合は遅くなる可能性あるけど致し方なし
  3. 順番を考慮する
    • @runInSeparateProcessの付いているテストを最後に持ってくる。そーすると下記のようになる
      1. setUpBeforeClass -> もともとのプロセスのsetUpBeforeClass
      2. this is static method. -> test_bのecho
      3. setUpBeforeClass -> test_aの設定の別プロセスのsetUpBeforeClass
      4. is this static method ? -> test_aのecho
      5. tearDownAfterClass -> test_aの設定の別プロセス or もともとの tearDownAfterClass
      6. tearDownAfterClass -> test_aの設定の別プロセス or もともとの tearDownAfterClass

最後

微妙にハマり、半日は浪費してしまった気がする...😰

プロセスが並列に動いて処理をしているので(プロセス同士は互いに考慮せずに稼働する)、タイミングというか、ケースによっては必ずこの上記のような順序になるとは限らない...😓

副作用は色々あるなぁーと実感しました

フロントエンドのコードベースの改善話(1st step)

はじめに

抱えていた課題感

  • フロントエンドのモダン化は結構前からの課題だった
  • 今までのコード達はjQuery + pluginをダウンロードして、サーバに配置して、読み込んで、自分で直接書いたjavascriptも読み込んで頑張ってた
    • DOMをガリガリ書き換えて頑張ってた。そろそろツライ
  • ただ書き換えるにしてもフロントエンドの移り変わりが早くてコレというのが無いなぁ

改善方針

  • いきなり全て書き換えることなど無理だし、ビッグバン・アプローチは怖すぎなので当然避ける
  • 何に書き換えるか問題は別途考慮が必要なのでちょっとおいておく
    • 自分たちの利用用途にあるFWだったりを検討するのに時間が必要なので
  • とりあえずは各所に散らばったjQuery + pluginを読み込んで、そのままjavascriptを書いているやり方を止めよう!!
    • この方法はバージョン管理もバラバラになりがちだし、ちゃんと動くのかというテスト的なもの不安がありすぎる...
    • なのでjQuery + pluginはnpm管理して、es6で書くようにしてwebpackでビルドしてってするようにした
    • ついでにwebpackでoptimizeもしとけば少しはパフォーマンスも良いだろう
    • まぁちゃんとパッケージ管理するところからスタートする!!
    • これ以上傷口を広げない作戦

いざ改善

ハマった点

  • jQueryはもはや全画面で使ってるのでglobal用にnpm管理のところから出力したいなぁ
import 'jquery';

上記だけのファイルでwebpackでdestするようにしたが、グローバル参照ができなかった😱

解決方法

  1. webpackのProvidePlugin,loaderとnpmのexpose-loaderを使った

  2. グローバル変数に代入してしまう

window.$ = $;
window.jQuery = jQuery;

結局はProvidePluginloaderを使っておいた方が無難な気がしたのでこれにしました。

最後

  • とりあえずはこれ以上負債を出し続けなければいけない状況は防げたかなと -> 傷口を広げない作戦
    • サービスを運用している以上、一旦止めることもできないし、日々の不具合対応やビジネス的にやらなければいけない新規施策とかはあってというツラさがある
    • そんな中でも直ぐに負債になってしまう前のコードの書き方でやらなければいけないのは精神的、モチベーション的にツライのでこの作戦は良いと思ってる💪🏽

iosアプリからのwebviewはレンダリングは通常のブラウザに比べたら遅いよねという話

はじめに

  • あるプロダクトでIOSのネイティブアプリからwebviewで既存のページを参照した時のレンダリングのメトリックスの話
  • そもそも半分わかっていた事ではあるが、普通のブラウザでのレンダリングとネイティブアプリからwebviewのレンダリングを比べたら普通のブラウザのが早いに決まってるがそれを目の当たりにした話

計測したツール

  • New Relicのブラウザ版
  • 下記のグラフはネイティブアプリのwebviewから既存ページを参照をはじめた時を境にしたNew RelicのApdexのグラフの図です
  • アプリケーションサーバのパフォーマンスは変わらず
  • フロントエンドのパフォーマンスだけが悪化
  • このグラフの波があった時期になんの変更をしているかと言えばネイティブアプリからwebviewで既存ページにアクセスをはじめたぐらい

少し考慮をすべき点

  • ネイティブアプリではよく画面の遷移をよりスムーズにする為に一画面を描画するのにあえて複数ページ or 複数画像を事前に読み込んでたりするのでクライアント(モバイル端末)の仕事が多い点がある
  • でも数値的に顕著に悪化してしまってるのでこれはこれで考えどころ

まとめ的に言いたい事

  • フロントエンド周りの数値をKPIに据えて頑張っているチームはネイティブアプリのwebviewの部分はノイズになる可能性があるので外して計測すべし
    • 一概には言えないけどネイティブアプリの利点をフルに活用して必要な部分だけAPI化してネイティブアプリで描画するべし
    • ネイティブアプリのwebviewでのレンダリングのメトリックスは除外するようにNew Relicの設定を変えるべき
      • Enable via New Relic APM -> Copy/Paste Javascript Codeに切り替えてUAをサーバ側で判定して計測JSを出力する方法しか今のところ無さそうです
  • だいぶ今更だけど、ほぼwebviewだけの側アプリはユーザ体験としてはむしろマイナスんじゃなかろうか
    • ネイティブアプリを出す理由は色々とあるけど、より快適にサクサク使えるという意味においてはwebviewはなるべく無くすべき

phanを使ってPHP7化に向かって効率的にリファクタした話

はじめに

そろそろphp7化に向かって動きたいなぁーと感じてて互換性チェックとテストの手間のカットをするためにまずは利用していないコードを効率的に抽出して消したいなぁーと思ったのがキッカケです

コードの見通しもよくなるし、リファクタして不要コード、ファイル削除は皆嬉しいはず

phan

GitHub - phan/phan: Phan is a static analyzer for PHP. Phan prefers to avoid false-positives and attempts to prove incorrectness rather than correctness.

互換性チェックなら下記も使える

GitHub - sstalle/php7cc: PHP 7 Compatibility Checker

メインの話

php7との互換性チェックは別の時に書くこととして効率的なリファクタの話をしようと思います リファクタと言ってもどこからも参照されていないメソッドやファイルなどをガシガシ削減していく事をメインにした

phpmdで感じてた不満

  • publicメソッドでunuseメソッドの抽出ができない...privateはできる
  • ざっと眺めてるだけで使ってないpublicメソッドが結構あるなーと感じてたので効率的にあぶり出したい...
  • https://github.com/phpmd/phpmd

環境設定

<?php
return [
    'directory_list' => [
        '/php/app/'
    ],
    'exclude_analysis_directory_list' => [
        /php/app/tmp/',
        '/php/app/tmp_sp/',
        '/php/app/tests',
        '/php/app/migrations/',
    ]
];

実行

./vendor/bin/phan --progress-bar -x -o phan.log

オプションの説明

 -x, --dead-code-detection
  Emit issues for classes, methods, functions, constants and
  properties that are probably never referenced and can
  possibly be removed.

phan.logを眺める

結果

  • phpmdの時に感じてたpublicのメソッドのunuseを検出できないという不満があった(privateメソッドならできる)。けど100点とは行かないけどpublicなunuse メソッドの検出に成功した
    • FW部分とかで本当は参照しているけど検出してしまう部分は致し方ない
  • zero references to methodで指摘が出た部分がpublicでunuse methodという感じでcat phan.log | grep "zero references to method"でさらに絞ってみた
  • 結局上記のgrepで抽出したmethodをide(intellij)から検索して不要だったことを確認してからdeleteした😰
  • まぁでも効率的にリファクタはできたと思ってる💪🏽

気づき

  • Can run in the background (daemon mode)とあるので定期的にlocalの開発環境でも実行しようかなと思った
  • smartyから呼び出しているobjectのメソッドも解析対象として動いた
    • どうやって動いているんだろうと思ったけど、今回は前後の結果を見てちゃんと動いているなぁーというところまで確認した
    • イメージは下記
      • php側でuser情報を取得したmodel objectをそのままsmartyに渡す
      • smarty側でユーザのフルネームを取得するメドッドをコールする
<html>
<head>~~~
<body>
{$user->get_fullname()}
</body>
</html>

ちょっとしたオチ

  • function名を変数に入れて、その変数からfunctionを実行しているところは考慮されず、使ってないなーと感じて消してしまった。
    • bugを出してしまった😰
    • エラーログ監視で見つけてソッコー修正しましたけど...すまん

最後

  • まぁでも良かったんじゃなかろうか。効率的にリファクタできて

グループ内の合同勉強会でLTした

合同勉強会の概要

developers.cyberagent.co.jp

  • 同じサイバーエージェントグループのタップル誕生のアプリを運営しているマッチングエージェントと急成長スタートアップ x 技術的負債というテーマで勉強会に参加した時のメモ
  • 各プレゼンは上記のCyberAgentのdeveloperブログを読めばまとまっています
  • このブログでは自分がLTした時の話の内容を残しておこうと思います

LT:古株のValueの出し方

speakerdeck.com

主に伝えたい事

少し前提:これまでの経緯とか

  • サービス立ち上げからやっているエンジニアって本当に苦労の連続でろくなエンジニアリングなんてしていなくて、ただただ目の前のキャッシュが切れるまでになんとかしなきゃの連続だった。
  • 技術の積み上げなんてしている時間などなく、貯金の切り崩しの生活をする
  • なので当然、早期に技術的負債を作りやすい傾向にある。ごめん😓
  • サービスも成長し、新しいメンバーが入った時、新メンバーは現状のコードや運用の惨劇を目の当たりにする
  • 特にgit blameでだいたいは自分のアカウントが出てきて、なんでこんないけてない感じになってるの?的な質問攻撃連続(質問者には悪気はない)
  • 人を憎まず、コードを憎むとは言うものの、やはり自分はそこまでデキた人間ではないからdisられているかのうような感覚に陥る。。。反省
  • あの時はこーだった的に少しは言い返したくなる。
  • でも総じて雰囲気が悪くなっていく

ここからが本題で言いたい事

  1. 初期からいる古株の人はすべてを飲み込む覚悟で臨まないとプロダクトの成長には寄与しない。それが出来なければただの老害となる
    • 結局ドロ臭い作業を全て受け持ってるとか、成果の見辛い部分を担ってるとか色々と不満がある。
    • 新しく入ってくれたメンバーからは色々と問題点をあげられ言われ放題。
    • まぁ色々言いたい事はあるけど、ダメな所はダメでどんな背景があったとしても言い訳しててもしょうがない。そんな時間あったら1日でも早く改善する事を考えるべき
    • とにかく立ち止まっている時間などないし、過去を振り返って反省は重要だけど前に進むことのがもっと重要。
    • やるべき事はプロダクトを1mmでも良くする事だけで集中すべし
  2. その人のキャラにもよるけど、古株の振る舞いってとても重要
    • 周囲に対する影響度合いで言うと古株の振る舞いは重要。ただのいち社員の発言ではない事を覚えておく
    • 自分が抱える不満・本当はこうしたいけど出来ない歯がゆさ・立ち止まる事が出来ないストレスとか挙げたらキリないほどクソいっぱいあるけど全てを飲み込んで、プロダクトの為の発言行動、前向きな姿勢を見せる事で成長のギアが上がる
    • 逆に全てを飲み込めず、愚痴っぽくなると全体的に停滞し、プロダクトは良くならない
  3. 経営者のみなさん、エンジニア古株の苦しみを少しでも理解してもらって🍻しましょう
    • お酒の力を少々かりながら本音トークしましょう!
    • プロダクトを良くしていきたいという強い思いは同じです
    • 経営者の辛さも当然あるとは思いますが、お互いに腹割って🍻しましょう!語りましょう!

最後

  • 正直自分も最初は愚痴っぽくなってたし、理解してくれる人がいなくてツライ日々を過ごした。偉そうに書いておきながら全然出来ていなかった。ゴメンなさい🙇
  • 過去を振り返るならゴメンなさいという以外何もないです🙇
  • 自分はデキた人間ではないので今でも口から出そうな時もあるが、少し立ち止まってプロダクトを良くするには今何が必要かだけを考えるようにしている