Shiopon Labo

しおぽん(@shiopon01)の個人ブログです

炎上プロダクトと、従事したエンジニアの心情

今年は初めて受託開発の炎上を経験したので年が明ける前にその時の心情を書き記しておこうと思う。あくまで従事したエンジニアの心情であるので、案件については言述していない。

本題

自分の経験した炎上はスケジュールが圧倒的に短くて発生したタイプの炎上だった。この記事ではスケジュールが短すぎた場合、エンジニアの心情はどういったものか、プロダクトはどうなるかを記述する。

スケジュール

とりあえず、納期や工数をマネージャー層が全て決定した状態でエンジニアに丸投げするのはやめよう。

ふつう案件にアサインされたエンジニアは要求仕様書から機能の洗い出しを行うが、この時点で 納期が短すぎるのでは? となった場合はその時点からマネージャーに対して 強い不信感 を抱き始める。(逆に、期間が長いと感じたらマネージャーへの好感度は上がる!)

納期を変えることはできないのでしぶしぶ開発は始めるが、実際に時間が足りなくなった時は クソみたいな見積もりをしたマネージャーの尻拭いをさせられている という考えが絶対に付きまとうので、精神上も良くない。そしてこの時のモチベーションは世界最低ランクだ。

この現象の対処法としては、やはりアサインが想定されるエンジニアも見積もりに参加させることが一番良いと思う。作業者自身もマネージャーと一緒に見積もりを行うことで、作業者に納期への納得感を与えることができるし、なにより技術を良く分かっていないマネージャーの適当なクソ見積もりを防ぐことができる。

この点からも、やはり現役エンジニア(実際の作業者推奨)を見積もりに参加させるのは必須と感じた。

プロダクトの品質

開発(プログラミング)に費やす時間の多くは アルゴリズムを考える 時間でもある。自分は特にその傾向が強く、一旦の実装をとりあえず作ってから綺麗なコードに書きなおすことが多い。

これは実際に案件のスケジュールが完全に遅れた状態になって分かったのだが、スケジュールが切羽詰っていると自分は製品を作るためのプログラミングではなく 帰るためのプログラミング を行うようになるらしい。

帰るためのプログラミングが何かというと、先述した アルゴリズムを考える 時間を大幅に省き、一旦の実装( HACK 的実装)のままどんどん機能追加を行うことだ。なんたって時間の余裕がないので、 綺麗なコードへの書き直し = 追加の残業 となる状態で自分はコードのリファクタリングまで行えなかった。なぜなら、絶対に残業はしたくなかったからだ。(結局時間が足りず、機能追加で残業や徹夜までしたが)

これがプロダクトの品質に悪いのは明白だが、エンジニアの精神状態にも大きなダメージを与える。コーディングする度に自分やチームメンバーのソースコードを見てリファクタリングしたい気持ちを抑え、「俺はこんな実装をしたいわけじゃないのに…」と思いながら新しい機能を追加していたあの頃は、きっとエンジニアとしては死んでいたのかもしれない。

プロダクトの品質はそのまま改修のしやすさにも繋がる。一時的な実装が多いということは、次に機能追加や改修の案件を担当した人に負債がのしかかるということだ。時間が無いなら仕方ないが、出来るだけ綺麗なコードを心がけたい…。

テスト

リファクタリングを行う時間が無いと言うことは、単体テスト結合テストのコードを書く時間も無いということだ。いや今回の場合、初めの頃はなんとかテストを書くスタイルだったが、度重なる機能追加と機能変更などの作業増加によって書く時間が明らかに無くなったと言ったほうが正しい。

今回で言うとテストチームがバグ出しを頑張ってくれたので、プロダクトとして最低限の品質は保障できた。中には単体テストをちゃんとやっていれば出ないようなバグも数あり、テストの大切さを改めて実感。(何よりも余裕を持ったスケジュールのほうが大事だけどな)

自分への影響

自分の精神的なストレス耐性は低いらしく、残業と徹夜はかなりしんどい思い出だった。

生きる活力がかなり削がれていたし、具体的には唇がよく切れるようになった。メロンパンを食べた時は、かじった部分が赤くなっていたくらいだ。

おわりに

この遅れが見積もりの失敗であれマネジメントの失敗であれ、どちらにせよ 遅れ (極端に言えば炎上)はプロダクトの寿命を縮めることに繋がることに間違いはない。

それは純粋なコードの品質の低さ、テストの未実施などもあるが、何より疲弊したモチベーションの低いエンジニアから生み出されたプロダクトが良いものであるはずがないからだ。マネージャーにはエンジニアのモチベーションを第一に考え、慎重に見積もりやマネジメントを行ってもらいたい。

そしてやはり、残業は悪い文明である。

WindowsでCaps LockをCtrlに、JISキーボードをUSキーボードにする方法

Windowsをよく再インストールするけど、その度にCaps LockをCtrlにする方法を調べている気がする…。年末なのでまた再インストールしました。

(備忘録。そのうちちゃんと書く)

regedit

Caps -> Ctrl

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]

name value
Scancode Map 00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

JISキーボード -> USキーボード

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters]

name value
LayerDriver kbd101.dll
OverrideKeyboardIdentifier PCAT_101KEY
OverrideKeyboardSubtype 0

参考

Windows/TIPS/レジストリを修正してCAPSLOCKの割り当て変更 - yanor.net/wiki

今更だけどghqを使ったリポジトリ管理を布教したい

ghq を使ってない人は人生の1割損してる。

本題

自分が ghq を使い出して数年経ったが、周りには案外、こういうリポジトリの管理ツールを使っていない人が多いらしい。絶対リポジトリの管理ツールはあったほうが良いので、ここで今更ながら宣伝しておく。 ghq 使います。

Goのインストール(準備編①)

まずはGoのインストールから。自分は goenv を使っている。(言語のバージョン管理は ○○env をよく使ってる)

goenvのインストールはこちらから。

goenvのインストールが完了したら、goをインストールする。インストールできるバージョンは goenv install --list で確認できて、このリストは ~/.goenvgit pull したら更新される。

$ goenv install --list
  (省略)
  1.11rc2
  1.11.1
  1.11.2
  1.11.3
  1.11.4

目的のバージョン(たぶん最新バージョンでいい)を見つけたらそのバージョンをインストール。インストールしたGoは goenv global で設定できて、 goenv versions で確認できる。

$ goenv install 1.11.4
  (インストールのログ)

$ goenv global 1.11.4
$ goenv versions
* 1.11.4 (set by /home/user/.goenv/version)

GOPATHの設定

実はGoには元々リポジトリ(外部ライブラリ)を管理する機能が備わっている。

リポジトリの管理は環境変数 GOPATH で設定されているディレクトリ(デフォルトは ~/go )で行われて、 go get で取得したリポジトリはここに入るようになる。ソースは $GOPATH/src に保存されて、 ghq みたいにバイナリが付属するやつは $GOPATH/bin にバイナリが入る。

ただの外部ライブラリ管理ディレクトリのように思えるが、Goのプログラムを開発するときはリポジトリGOPATH の下に置いておかないとimport周りが面倒くさくなるので(経験談)、実は普通のリポジトリもここに置いて一元管理しておいたほうが良い。そのため、 GOPATH にはこれから自分がリポジトリ管理に使いたいディレクトリを設定しておく。

自分の場合は ~/Work を設定している。リポジトリとかプログラムの管理は全部ここでやってて、 $ work~/Work に飛ぶエイリアスもある。(あと、 $GOPATH/bin をパスに追加しておこう)

# bashrc
export GOPATH=$HOME/Work
export PATH=$GOPATH/bin:$PATH

function work { cd ~/Work; }

ghq(とpeco)のインストール(準備編②)

pecoは go get でバイナリを取得できなくなったこともあり、Linuxだとちょっとだけ手間になった。ここではダウンロードしたソースをbuildする方法でpecoをゲットする。( releases/peco_linux_amd64 のところはOSによると思う)

$ go get github.com/peco/peco
$ cd $GOPATH/src/github.com/peco/peco

$ make build
$ cp releases/peco_linux_amd64/peco $GOPATH/bin

ghqのインストールは go get で行える。これだけで $GOPATH/bin にバイナリが入るので、それを利用できる。

$ go get github.com/motemen/ghq

ghqの設定

ghqgo get のようにリモートリポジトリをまとめる機能を持っていて、このためにGOPATHのようにghqの設定も記載しておかなければならない。設定するファイルは .gitconfig[ghq] 部分で、 一番下に次の例のように、 $GOPATH/src のパスを追記するだけで良い。

環境変数使えるのかな……。自分は ~/Work/src を設定していた)

[ghq]
  root = ~/Work/src

インストール作業は以上。

スーパージャンプ!(本編)

結論から言うとこの関数をbashrcに追記して使用する。関数名は何でもいいが、自分は入力のしやすさから repositoriesre としている。

# bashrc

function re {
  local path=$(ghq list --full-path | peco --query "$LBUFFER")
  if [ -n "$path" ]; then
    if [ -t 1 ]; then
      cd ${path}
      echo 'jump to' ${path}
    fi
  fi
}

仕組みとか

ghq が使えるようになって設定も完了しているなら、現在 ghqgo getリポジトリ管理に使うディレクトリは同じものになっているはずだ。( $GOPATH.gitconfig の設定)

試しに ghq list で確認してみると、さっきGoでクローンしたリポジトリが出力される。そして、今回欲しいのは --full-path を付けたfull pathのリスト。

$ ghq list --full-path
/home/shion/Work/src/github.com/motemen/ghq
/home/shion/Work/src/github.com/peco/peco

この結果をpecoに食わせて、pecoのQUERYと選択した行を出力してくれる機能を使ってリポジトリを絞り込んでいる。ここで取得したパスは変数 path に保存され、チェックなどが行わた後にそれを使って cd で移動する。 echo は消しても良い。

Gitリポジトリのクローン

Gitリポジトリのクローンは ghq get を使う。これは別に go get でもいいけど…。

ghq get https://github.com/githubtraining/hellogitworld

これで設定したディレクトリの下に、パスで区切られたいいかんじの階層でリポジトリが保存される。 ghq list を実行しても確認できるはず。

ローカルにしかないリポジトリの管理

ghq list で取得できるのは、指定ディレクトリ以下の .git を含むディレクトリのパスだ。( ghq get で取ってきたものだけ、というわけではない)

自分の場合、ローカルのリポジトリlocal というディレクトリに保存している。パスで言うと $GOPATH/src/local 。ここで例えば rails new とかで自分のプロジェクトを生成し、 git init.git を作成することで ghq list でパスを取得できるようになる。

$ ghq list
local/my-local-project

実行例

$ pwd
/home/user

$ re
jump to /home/user/Work/src/github.com/peco/peco

$ pwd
/home/user/Work/src/github.com/peco/peco

エンジニア、会社に給料を上げてもらうのは難しい 説

この記事が腑に落ちたので、思いついたことをちょっと書く。

blog.tinect.jp

本題

それなりの給与がもらえるかどうかは「人に投資すると売上が伸びる会社で働いているかどうか」

この一文が腑に落ちた。これは言い換えると、「人に投資することで売上が伸びる会社は、社員の給料を上げやすい」ということだろう。

エンジニアは職業柄、投資をされたところで会社の売上を直接伸ばすの難しい。そして何より、投資の結果が見えにくい。(知識労働者あるあるなのでは)

このような原因もあり、多くの企業でのエンジニアへの投資は最小限とされている。つまり、給料が突然上がることがほとんどない。

ほとんどの場合、エンジニアへの投資は先行投資だ。スタートアップ企業では、良いエンジニアを集めてモチベーションを高めるために先行投資を行う光景をよく見る。ただ、これはスタートアップだから先行投資が行われるというわけではなく、事業が少なく、投資の結果が見えやすいスタートアップが投資を行いやすい環境にあるだけなのだろうが…。(お金がないスタートアップの話もよく聞くので、一概にこうとは言えない)

逆に、体力はあれどモチベーションのような不確定なものに投資を行わない大企業などは先行投資ではなく成果報酬となりがちだ。社員が多い場合はなおさらその傾向がある。こういう企業では残念ながら、経営者は今エンジニアに払っている給料が十分なものだと考えているので、エンジニアの給料を上げるなんてことはほとんどしない。開発環境(PCなど)への投資のような、比較的安価な先行投資すら知ったことではないという経営者も多いのも事実。

PCの性能は生産性に直接繋がるが、残念ながらモチベーションへの投資がそのまま利益に繋がるわけではない。そのため、こういった先行投資を行わない企業で働くエンジニアが自分の給料を上げてもらうのは、大変な活動となりがちだ。

そのためにはエンジニアは何をするべきか。成果が見えにくいのなら、実績として結果が残ることを行うしかない。ここで言う結果とは、 直接的な会社の利益 である。

エンジニアの給料を上げる方法(例)

直接的な会社の利益とはどういったものか。以下は簡単な一例。

例えば、 社内のワークフロー改善を行い続ける ようなことだ。これはモチベーション改善や環境改善とかではなく、もっと根本的な、仕事の工数を削減するようなワークフローの改善という意味。削減された工数はだいたい数値に現れるし、改善したことによって社員や顧客の満足度が向上したのならなお良い。いわゆる業務コンサルのような仕事。

または、実際に 自分が仕事を引っ張ってくる 選択もある。自分が所属している会社が中小企業であるなら、自分がそれなりの仕事を引っ張ってくれば間違いなく会社の利益となるからだ。(これは営業のような仕事…。)しかし、所属している会社が大きいとこれは難しい。大企業ではそれなりに単価が高い仕事を求められがちなため。

このような、直接会社の利益となる活動を行うことが確実にエンジニアが給料を上げる第一歩だと考えた。エンジニアではあれど、直接的な利益を生み出そうと思うとエンジニア以外の仕事もこなさなければならない。

この結果を持って、「私は業務のワークフローを改善し、結果として○時間の工数を削減した。(会社のために仕事を持ってきた)そして今後もこの活動を行い続けるため、私に投資してもらいたい。」と強気に役員とかに凸して認めてもらおう。

エンジニアらしい選択肢として、 エンジニアとしてめっちゃ頑張る (ヘルプ入りまくって、ツール作りまくって、社内活動頑張る)という選択もあるが、これで給料が上がるかは難しい話だ。その活動を認めるかどうかは経営者次第なところが大きく、会社としてのエンジニアへの理解が求められる点でもある。(こういうことができる人は、エンジニアへの理解がある会社で働くべきでは)

おわりに

エンジニアが給料を上げるには、例えば次のような、直接的な利益を生み出すエンジニア業務外の活動などが効果的だという話をした。

  • 業務の工数を削減できるようなワークフロー改善の継続(コンサル)
  • 自分が仕事を引っ張ってくる(営業)

キーワードはおそらく「会社の利益」と「継続」。

エンジニアへの理解が無い会社だと、エンジニアの満足度向上などモチベーションに関わる活動のほとんどは評価のポイントにならないので、その点は注意。

給料を上げる難易度は会社によって違う。エンジニアへの理解があり、なおかつ体力のある企業であれば給料を上げることは容易だろう。しかし、エンジニアへの理解が無い会社であるなら、それは難しいものになる。多くの企業では管理職になることで給料が上がるキャリアプランが準備されているが、これもエンジニアとして働きたい人には辛い選択でもある。

どうしても難しそうなら 転職するしかない(オススメ)

大規模アプリ開発系コンテストでの生存戦略

ここで言う 生存戦略 とは、いかにコンテストで勝ち抜くか、という点に焦点を当てたものだ。コンテストでの優勝にはある種の運、例えば発表する環境や審査員のバックグラウンドなども関わってくるため、優勝を目指すのではなく、いかに優勝に近付くことができるかという記事。

本題

大規模なアプリ開発系のコンテストでは、単純なアプリを作るだけでは審査員の目に止まらない。

こういったコンテストでは大概、そのアプリを使うことによって 日常に起き得るどのような問題を解決できるのか という点が最も重要視されており、これをクリアすることが開発者にとっての最初のハードルになる。(中小規模のコンテストでは純粋な面白さが重視されることもあり、この限りではない)

だからといって、ただ単純に問題を解決できるアプリを応募しただけで勝ち抜けるという話でもない。

自分がいくつかのイベントに参加し、実際に多くのチームの発表や作品を見て感じた、勝ち抜くためにアプリに組み込むべき基本的な要素は次の4つだった。この何れかが抜けているだけでコンテストで勝ち抜くことは難しくなる。

  • 問題提起
  • 解決方法の提案
  • 結果と規模
  • フィードバックと反映

この要素は必ず必要なもので、ほとんど例外はない。(ハッカソンは別)

また、コンテストで会場展示・プレゼンを行う場合は、この4つの要素を端的に分かりやすく伝えるためのトークスキルなど、マーケティング能力のようなものも必要になってくる。優勝しようと思うのであれば、ここまでの準備を完璧にこなす必要がある。

以下の項目では、各要素で何を行うか・どんな点に注意すれば良いかを記載している。

問題提起

アプリを開発する前に、まずは身の回りでどのような問題が発生しているかを探る必要がある。そしてコンテストに応募するアプリはその問題を解決するものであるものが好ましい。具体的な問題へのソリューションであることで説得力をもち、審査員に納得感を与えることができる。

さらに、ここで提起する問題はグループの日常的な問題であればなお良く、ターゲットは若ければ若いほうが良い。なぜなら若い世代のグループ、例えば学校のクラスの間で話題になれば、利用者は特に爆発的に広がりやすいからだ。より広い範囲で問題を解決できるものはそれだけ評価が高い。

コンテストではそのアプリが正式に公開された後の道筋が見えるかどうかも一部では評価の対象となる。ただ問題を解決するだけでなく、利用者をどのようにして増やすかも考えなくてはならない。この時、例えばターゲットが若い世代のグループであり、実際に問題解決を行えており、口コミで広がりそうなものであれば評価はより高いものとなる。

ポイント

  • 身の回りの、誰もが感じるような問題を提起する
  • グループか若い世代、またはその両方が抱える問題を提起したほうが良い
  • 提起される問題は誰もが納得できるものである必要がある
    • ニッチな問題でも、具体的な例を見せるなどでカバーは可能

解決方法の提案

提起した問題をどのようにして解決しようとしたかという部分。この部分が実際にアプリ開発を行うフェーズになる。

まず、提起した問題をどのようなアプリで、どのような機能で解決に導くかを考えなければならない。そしてここで提案する解決方法は確実に現在の問題を解決、または緩和できるものでなければならない。この解決方法は難しい技術や最新の技術を使うよりは、簡単でも 現実的 であるほうが好ましく、結果として納得感も与えられる。(作るのも楽だし、展示やプレゼンをする場合は質疑応答も答えやすい)

実際のアプリ開発だが、ここではできるだけUI/UXに拘るべきだ。審査員は背後の技術やコードにはほとんど興味を持たず、問題に対して得られるソリューション、そして扱いやすさや操作感でアプリを評価する。APIの設計やソースコードのロジックに拘るならば、その時間をできるだけフロントエンドの開発に当てたほうがコンテスト的には良い。

ポイント

  • 問題を確実に解決・緩和できる解決方法を提案する
  • 簡単でも現実的な解決方法と技術を提案する
  • バックエンドには拘らず、フロントエンドにできるだけ時間を割く

結果と規模

提案した解決方法を実施した結果、実際にどれほどの規模で問題を解決することができたかの項目。具体的にはユーザーテストを行うフェーズ。

多くの作品は 解決方法の提案 で止まってしまって、ユーザーテストまで行われていないことが多い。しかしこのユーザーテストはコンテストで勝ち抜くためには必須と言っても良い項目であるため、必ずやっておいたほうが良い。ユーザーテストを実施していないのであれば、その作品はユーザーテストを実施した他の作品に敗北することになる。

なぜ重要かというと、このフェーズをこなして具体的なテストの年齢層や手応えを提示することでより強い納得感を審査員に与えることができるからだ。ここで得られる納得感は何よりも重要で、単純なユーザーテストの結果だけでなく、例えテストだとしても 実際に運用された事実 を審査員に印象付けることができる。幅広い年齢層にテストしてもらえたならなお良く、得られる納得感も強いものになる。

他にもアプリ以外の面だが、開発者の行動力やマーケティング能力、広域的なコミュニケーション能力などを評価してもらえる可能性がある。これは公開後にアプリを広めることができるか、ユーザーが望むものを作ることができるかなど、先述した そのアプリが正式に公開された後の道筋 と繋がっている。

ポイント

  • 解決方法の提案 で終わらないこと
  • ユーザーテストを行い、提案する解決方法の納得感を与える
  • ユーザーテストを行った事実、実際に運用したという事実で印象を与える

フィードバックと反映

ユーザーテストは 結果と規模 で終わりではない。フィードバックはそれに対してのアクションとセットだ。実際にユーザーテストを行いどのようなフィードバックを得たか、そのフィードバックをどのような形で実現したか(または、どのような理由でフィードバックを実現しなかったか)も重要な点になる。

ユーザーテストの結果どのようなフィードバックを得たか、そしてそのフィードバックに対しての自分のアクションをセットにして提示することでより強い納得感を審査員に与えることができる。自分のアクションをセットにできないのであれば、そのフィードバックは提示しないほうが良い。

これもアプリ以外の面となるが、フィードバックの反映は実際、フィードバックから問題点や妥協点を探り、自分のアクションに落とし込めるかを問われる。これは先述したように、ユーザーが望むものを作ることができるか、またはアプリそのものの寿命にも関わる部分であるので、このあたりも評価される可能性がある。

ポイント

  • フィードバックは必ずアクションとセットで提示する
  • フィードバックに対してどのような改変を行ったか、行わなかった場合はなぜそうしたのかを提示する
  • 協調性を求められる部分なので、そのアクションに至った結果もあったほうが良い

おわりに

納得感、納得感としつこく言ってきたが、これは本当に重要な点で、コンテストで勝ち抜こうと思うなら最も意識しなければならない点になる。なぜなら、どれだけ良い物を作ってもその意味や熱意を相手に伝えることが出来なければ、絶対にコンテストを勝ち抜くことができないからだ。

コンテストを勝ち抜く作品には単純に問題を解決する力(アプリの品質)のみならず、今後実際に広く運用される未来が見えるか、その際に確実に様々なシチュエーションで問題解決に貢献できるかも問われる。この部分をクリアするには幅広い層の実際のユーザーテストとフィードバックが必要不可欠であり、これを行うためのマーケティング能力や広域的なコミュニケーション能力も必然的に求められる。

最後になるが、企業のAPIを活用したコンテストの場合、その企業の全てのAPIを使う必要はないということをアドバイスしておく。LINE BOOT AWARDSは LINE Messaging APILINE Clova を使ったコンテストだったが、最優秀賞の2作品はどちらもMessaging APIしか使用していなかった。結局求められているのは、どのような問題を解決できるか、ということだったのだ。