病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

年の瀬なので26歳の1年間を振り返る

エンディングノート」書いた

あと60年くらいは生きたいが、遺言書を書いた。

友人や祖母が亡くなったりするイベントがあったので1年前くらいから書こうとは思ってて、この度生活環境が大きく変わったので(とても良い)、引っ越しに合わせて、書いた。「遺産を誰に遺贈するか」「寄付」「葬式・納骨」について記載している。

実は数十万〜数百万での遺産トラブルというのも多いらしく、若い人にもエンディングノートを書いておくのをおすすめしたい(僕はわりと勝手にお金が貯まるタイプなので、4年も会社勤めしてるくらいの資産はある。新卒からそうなので、今の給与とは特に関係ない)。ちなみに、未婚の場合、遺留分は親に行く。

僕が書いたのはコクヨの遺言書キットだけど、Amazonエンディングノートとかでググると出て来て、結構カジュアルに書けるのでオススメ。

自分がこの1年で触った技術とか

この1年は、AWS、Docker、Python、Keras、サーバーレス、SPA、React、Vue、re:dash、ログ基盤、、、あたりを触ってた気がする。

特に去年に比べて新しいのは、SPA関連で、これは結構自分の身を助けた。社内サービス(XWire)の管理画面勝手に作ったり、プロトタイプツール作ったり。

DockerとSPA(特にVueは、楽だ。チーム開発には汚くなりやすいかもしれないが)は、「絶対にやった方がいい」と自信を持っておすすめしたいものだったりする。

来年はデータ可視化・分析周りと、SPA→アプリの分野(React Nativeなど)に殴り込みをかけたい。

あと、GoとRustにチャレンジしたい。

情報収集の方法

英語オンリーのアカウント作って、英語の情報アカウントとかをフォローしている。例えば、HackerNewsとか、海外の大御所とか、Github Trendingとか。はてブで入ってくる情報とはまた異なる種類の情報が入ってきて、大変良い。もっぱらこっちのアカウントをTwitterで開いている。

フォローしまくったら凍結されたりしたので(明らかに正しいTwitterの使い方なのだが...)Twitterアルゴリズムは頑張って欲しい。。。

最近思うこと①:時間の使い方

とあるブログ記事で読んだ「定時が、ギョームでいっぱいだったら『忙しい』状態」という話は、「そうだよなぁ〜」と感銘を受けたりした。

暇ができたらイノベーティブになるのかは知らないが、仕事での意思決定・技術選択の根拠になるのは、たいてい、仕事以外で得た知識だったりする。むしろ仕事だけで得た知識で意思決定している人がいたら、絶対に信頼したくない。

であればこそ、定時内に「仕事」以外の仕事をぶち込んでいかないといけないし、定時外にプロジェクトを増やしていかないといけない。いわば、「トリプルワーク」を来年はしていけたらなと思っている(いわゆる副業ということではなく)。

最近思うこと②:会社との向き合い方

僕は、(生涯)年収の最大化を目的として、僕のキャリアを今の会社にベット(Bet;賭け)している、のだと思うようにしている。今日でちょうど、2年間をベットしたことになる(実際にはそれ以上だが、、、)

リターンの期待値を最大化するのであればそれなりの賭け方があるし、逆に、ポートフォリオを組むこともできる。

最近思うこと③

最近、あらゆる不便を「繋がっていない、という感覚」と自分の中で言語化している。この言語化が、この1年で自分にとって最も価値の高いものだったかもしれない。

例えば、アプリのマーケティングをしてお金を儲けようと考えたときに、アドネットワークで広告配信して、ユーザーがアプリをインストールし、アプリ内でアドネットワークの広告を見てマネタイズする。さて、「アドネットワークAを経由したユーザーで、いくら広告が儲かったか」が“直接”わかるかというと、わからない(少なくとも無料では)。「このアドネットワークでプロモーションするとROIが高いですね」ということを知りたいのに、繋がってない、という具合。

この「繋がってない」を解決できるサービスを作りたいなと思っていて、解決できると「マジで便利」なのかなーと思っている。とは言え僕は飽きっぽいので、それをどうマネージメントするかに苦心している。

Python の開発に VSCode を使ってみた雑感

普段 Python 書くときに使ってるエディター

  • PyCharm (Vim Emulator を入れてる)
  • たまに Vim

PyCharm の気に入っているところ

  • 型推論がすごく良い。動的型付けな言語にとって、これはかなり良いメリット
  • Vim の Emulator が結構良い

PyCharm の不満

  • Vim の Emulator が入っているとはいえ、Vim じゃない
    • 例えばマクロがない
  • 普段 Docker、 docker-compose を使っているが、Docker内のデバッグ(リモートデバッグ)は有償版でしかできない
    • 体験版使ったときは、動きすらしなかった。同僚によると今は大丈夫らしい
    • 会社の予算で買ってもいいんだけど、ホスト(mac) で Python 動かせばいいので買うほどじゃない
  • direnv、flake8、mypy などのツール・ライブラリに対するサポートがない

VS Code の雑感

  • リモートデバッグ使える、すごい
  • 挙動がさくさく動く。Atomより気に入った
  • flake8、autopep8、mypy など外部ツールを最初から想定しているのが良い
  • direnvもエクステンションで行けた
  • 内部で ctags を使っているらしく、ctags 入れないといけないのにハマった(ドキュメントに書いてあった)

VS Code の不満点

  • 型推論が弱そう
    • 大きいプロジェクトだと、mypy のサポートもあんまり上手くいかない。設定が悪く import がうまくいってないのかもしれない。。。
  • PyCharm にある

VS Code のリモートデバッグ

  • 問題なく動いて感動
    • 自分は Docker 内でしか試してないが、恐らくリモート環境にあるサーバーでも動くだろう
  • 最初はセットアップがちょっと面倒くさい
    • ptvsd を Docker 内でインストールしないといけない
    • docker-compose の commandpip install ptvsd && python hoge.py した

VS Code の Vim Emulator

  • マクロが動く!すごい!
  • キーバインドが設定できないものがある。例えば、 vi( みたいにビジュアルモードに関係するやつが設定できなかった
  • .vimrc は読めないので個別の設定が必要
  • 一部の Vim プラグインにネイティブで対応してるっぽいのがすごい

総評

  • PyCharm に比べて、 外部ツールに対応しているのがすごく良かった
  • リモートデバッグできるのも良い
  • けど、型推論系が弱いのと、自動の import がなくてつらいのを解消したい

こうして人は拡張機能を作るのか。。。

「GraphQLは何に向いているか」に対してのちょっとした反論

k0kubun.hatenablog.com

非常に丁寧に書かれていると思うのですが、少し反論したい部分があるので、記載したいと思います。

GraphQLのキャッシュ効率について

クエリをパースしないとキャッシュの可否を判定できないため、HTTPキャッシュが難しい

こちらに関して、2つの観点から反論してみたいと思います。

まずに、GraphQL は GET リクエストでも送ることができます。Serving over HTTP | GraphQL によると、http://myapi/graphql?query={me{name}} のような URL の GET リクエストができます。(※そもそも、これ自体は GraphQL の絶対的な制約ではなく、 GraphQL を一般的に HTTP で提供するときのプラクティス、という位置づけです)

そして、GraphQL は 1 回のリクエストで送らなければならないわけではない、ということです。

私は JX 通信社 で NewsDigest というニュースアプリを作っています。例えばニュースアプリであれば、「フィード」というキャッシュ効率の高いものあれば、「ユーザーの設定」というキャッシュできないものや、書き込むものもあります。このような例であれば、キャッシュ効率の高いリクエストとキャッシュ効率の低いリクエストをわけ、さらに mutation の操作のみ POST リクエストを送れば、CDNなどでもキャッシュ可能です。

これは REST API であれば、 GET /feedGET /settingsPOST /settings というリクエストにわかれるわけですが、 GraphQL の方が特別キャッシュしづらいというわけではない のではないかと思います。(※もちろん、リクエストをわけると GraphQL のメリットは下がります)

弊社がGraphQLを採択してみた理由

厳密には採用したものをリリースしようとしている段階ですが、弊社で GraphQL を採用したかった理由を述べたいと思います。

GraphQL に感じる大きなメリットの1つは、API と型とドキュメントがパッケージ化されている ことです。もちろん、 JSON Schema や API Blueprint を組み合わせることもできます。しかし、これがパッケージ化されていて、「GraphQL」という技術の標準規格であり、後付けの技術ではないというのは大きなメリットだと思います。「GraphQLのドキュメント読んどいてください」「GraphiQL触ってください」で話せるわけです。

もう一つは、 GraphQL はクエリが定数であり、「どうリクエストするか」を定数化できる というところです。このメリットが触れられていることを見たことがないのですが、これは GraphQL にしか解決できない(?)大きなメリット だと思います。「定数化」というのはどういうことかというと、 { hoge { fuga, piyo } } みたいな「どのオブジェクトを取得し、このフィールドが必要である」という情報を「定数」として、AndroidiOSJavascript、サーバーサイドで共通化できる、ということです。例えば「アプリ立ち上げ時にはこのリクエストを送って下さい」という指示を、クエリ定数 として、各プロジェクトで共通化でき、サーバーサイドのスナップショットテストでクエリの互換性を担保したり、、、みたいなこともできます。

※ 「クエリを定数化」と書いてしまったのですが、クエリ自体が定数なので(その代わりに引数や変数の概念がある)、表現を修正しました

逆に、GithubFacebook のようにリソースが多かったり、サーバーサイド開発者がクライアント側を書いたりは(あまり)していません。

また、キャッシュ効率について「CDNでもキャッシュできる」とは述べたのですが、フィードのパーソナライゼーションなどが必要になるので、採用していません。

個人的に考えるGraphQLの大きな問題

クエリのパースが複雑なため、ライブラリ依存になる、という点です。

例えば、2017 年 9 月現在、 Python の GraphQL ライブラリには次のように書いてあります

This library is a port of graphql-js to Python and currently is up-to-date with release 0.6.0.

0.6.0 は 2016 年 5 月の実装です。「各言語ごとの GraphQL ライブラリが対応してないものには対応できない」という潜在的な問題を含んでいることになります。もちろん、OSS なので Contribute すれば良い、ということでもあるのですが。

もう一つ、一般的に HTTP 上の GraphQL のレスポンスはオブジェクト(連想配列)を返すので、でかい配列データ(ニュースフィードなど)を JSON Streaming でインクリメンタルに表示する、みたいなのが難しいんじゃないかなーと思ったりもします。

GraphQL を採択すべきでない理由をあげるなら

GraphQL は、あまり何かを制限するものではありません。 RESTful API のように使うことも一応可能です。

したがって、「GraphQLを使うべきでない」というケースというのは「RESTful API のような使い方ぐらいしかしないからオーバーエンジニアリングだ」というときなんじゃないでしょうか。

まとめ

  • GraphQL は何か制限をするものではない
  • GraphQL は型やAPIドキュメントをパッケージ化していて、クエリを定数として共有できるのもメリット
  • GraphQL が適さないケースは確かにあるが、キャッシュは問題ではないと考えている

GraphQL がもっと広まるとうれしいです。3 年後には「何だったのか」って総括されてそうですけど。笑

以上です。

補足

ブコメありがとうございます!

id:koyancya

定数クエリ、REST のエンドポイント増やすのとは何が違うのだろうか

ニュースアプリとかの場合を想定して、例えば、アプリの立ち上げ時に「トップのフィード」「ユーザー設定」を同時に読み込みたいとします。これはGraphQLでは次のように表現できます(※実際には引数や変数を宣言しますが、クエリ自体は定数です)。

GET /graphql

{
  feed {
    title, createdAt
  }
  setting {
    subscription, prefecture
  }
}

一方で、GraphQL でない場合、これを「定数」として縛ろうとすると、次のようなエンドポイントを生やす感じになってしまうかなと思います。

GET /app_startup

これでは、そもそも RESTful ではなくなってしまいます。また、「やっぱり立ち上げ時は、ユーザー設定読み込むのやめよう!」となったとき、API側を変更する必要が出てきてしまいます。GraphQL の場合、リソースを宣言してさえおけば、フロント側だけでリクエスト方法を固定できます。(で、答えになっていれば良いのですが・・・!)

Puppeteer を CLI で動かす Docker イメージ作った

また新しい Docker イメージ作ったので紹介する。

https://hub.docker.com/r/yamitzky/puppeteer-cli

Puppeteer とは?

github.com

Chrome Headless を Node で触るためのライブラリで、URLを見ると分かる通り、 Chrome のチームが出しているものです。

Puppeteer-CLI は?

Puppeteer を CLI から動かす、 Docker イメージです。現在は、スクショを撮る機能のみ対応しています。

Chrome Headless そのものを Docker で動かすのに比べてのメリットは、

  • Docker での連携を前提にしていて、 標準出力にスクショ結果を吐き出すことができる ※Base64エンコードされています
  • CSSを埋め込めるので、日本語フォントとかも行ける
  • 今後の発展性 ※ 現在は未対応ですが、今後 puppeteer のコードを実行できるようにしたいです。

使い方

標準出力に吐き出すときは、

docker run -it --rm yamitzky/puppeteer-cli --url https://yamitzky.com

日本語対応するときは、

docker run -it --rm -v "$PWD:/tmp" yamitzky/puppeteer-cli --url https://yamitzky.com --out /tmp/example.png --delay 1000 --css 'https://fonts.googleapis.com/earlyaccess/notosansjapanese.css' --style 'font-family: "Noto Sans Japanese"'

といった感じで動かせます。 Noto フォントシリーズは、韓国語とか中国語にも対応しているものもあるので、読み込ませるCSSの設定を変えればいろいろできます。

Options:
  --width   Width of viewport
  --height  Height of viewport
  --out     File path to save. If `-` specified, outputs to console in
            base64-encoded                                        [default: "-"]
  --delay   Delay to save screenshot after loading CSS. Milliseconds
  --css     Additional CSS URL to load
  --style   Additional style to apply to body
  --url                                                               [required]

Examples:
  index.js --url=https://example.com

なんで標準出力に吐き出せると嬉しいの?

だいたい、こんな感じの使い方をイメージしています。

f:id:yamitzky:20170822004028p:plain

ECSの場合、標準出力に吐き出されたログを、CloudWatch Logsに出力することができます。CloudWatch Logs から Lambda を発火させて、 Lambda から Slack に投稿したりできそうだなーと思った次第です。

チーム開発における「ニワトリ」が適切に鳴くために

アジャイルスクラムとかの文脈で「ニワトリ」と「ブタ」という概念がある。

f:id:yamitzky:20170713001738j:plain

その言葉自体は結構ググれば出てくると思うんだけど、一つ寓話を引用してみる。要は、「ニワトリとブタ」のプロジェクトメンバーが「ハムエッグ」を作る上で、「ブタ」は自分の身を削っているのに対し、「ニワトリ」は身を削っていないですね、ということ。

ニワトリとブタがいた。
ニワトリは「さあ、レストランでもやろうよ」と言った。
ブタはよく考えてから「レストランの名前は何にしようか」と言った。
ニワトリは答えた。「ハム・エッグさ」。
ブタは言った。「僕は止めておくよ。君は産むだけだけど、僕は切り刻まれるんだよ」

recompile.net

※ 原典は シュエイバー・ビードル共著の「アジャイルソフトウェア開発スクラム」?

原義からずれるかもしれないが、自分は「ブタとニワトリ」をこう解釈している。

ブタ・・・開発チームのメンバーであり、開発工数を使ってプロジェクトにコミットしている
ニワトリ・・・マネージャーやステークホルダーや部外者であり、プロジェクトに関わってはいるが開発はしない

あまり好きではない言い方だけど、一言で表現するなら「現場」と「マネージャー」だ。ちなみに自分は、ブタになることもあれば、ニワトリになることもある。

ニワトリはなるべく鳴いたほうが良い

まず大前提として、開発チームも、マネージャーもステークホルダーも部外者も、自由に意見が言えた方が良い

逆に、開発チーム以外が意見が意見を言えない状態というのは最悪で、

  • 問題に気づいた人が報告できない状態になってしまう
  • 新鮮な観点の意見を取り入れられなくなってしまう

なので意見は、多ければ多いほど良い。それが、チームでモノづくりする一つのメリットでもある。ただし、意見を適切に取り入れることのできる限りにおいて、という前提が必要だ。

ニワトリが鳴くデメリット

ニワトリが自由に鳴ける環境の方が健全だけど、ニワトリの鳴き声は開発チームへの悪影響がつきものだ。

  • 「偉い人」の報告の重要度がわからず、目の前の開発が止まる
  • 既に話した仕様を再度聞かれていたりして、ストレスが溜まる
  • 報告義務が発生する上に、専門家ではないから理解に時間がかかる
  • エンジニアとの共通言語がずれていて、コミュニケーションに時間がかかる
  • 「偉い人たち」の言ってることが違っていたりすると、もう大変

注意してほしいのは、これが善意かどうかにかかわらず起こる可能性がある、ということだ。

偉い人が要望をあれよこれよと善意で提案して、現場が右往左往している、といえば、失敗経験が思い浮かぶかもしれない。

ニワトリが自由に鳴けるチームが健全だけども、鳴き方に問題があると、悪い問題が発生するのだ。

適切なニワトリの鳴き方

では、どういう風に意見・要望を伝えたり、悪い報告をすれば良いのだろうか?

僕が気をつけていることは、4つある(できている、とは言えなくて、後悔することも多いのだけど、、、orz)。

1つめは、重要度/緊急度を適切に定義し、選択権を委ねることだ。これから提案しようとしていることは、目の前の開発を止めてまでやってもらうべきことだろうか? 開発スプリントに差し込むべきものだろうか? もしそうでないなら、「急ぎではないので、一段落したら対応検討してください」とか「とりあえずバックログの一番上に積んでおきました」とか「優先度を明日の朝会で調整させてください」とか、そういうコミュニケーションを取るようにしている。目の前の開発を止めなくていいですよ ということを表現するようにしている。コードレビューにおいても「今じゃなくて良いんですが、今後こうしたいですねー」とか言ったりする。

2つめは、なるべく正確に表現することだ。特にバグレポートに顕著で、「再現方法」「生じた事象」「推測される要因」などを、誰が読んでも誤解なく読み取れるように書くようにしている(参考)。「誰が読んでも誤解なく」というのは、例えば、「アプリが動かない」ではなく「フリーズして操作できなくなる」というふうに、曖昧でない日本語を使ってあげることだ。

3つめは、ポジティブに取れる表現をして、決定権を委ねる(特にこれができてない、反省)。「◯◯かもしれないですね(これを前職で「かもトーク」と呼んでいた)」とか「◯◯も良いと思います」とか「◯◯と思ったんですが、どうでしょうか?」とか。自分の発言が正しく、相手に説明すれば理解してくれるという性善説に立てば、決定権は相手に委ねることができるはず。(意見が割れるときは、投票というテクニックを使います)

4つめは、聞く前に検索する。最近のチーム開発だったら、Slackとか使って、Qiita:team的なナレッジベースがあって、Github Issueベースで仕様が固まっていったりするので、検索すれば出てくることも多い。「検索してみたんですけど見つからなくて」とか言えば「ああ調べてくれたんだな」とポジティブに構えてくれる。むしろ、検索して出てこないのであれば、仕様がちゃんとドキュメントとして残っていないということなので、「ドキュメントをより良くしましょう」という改善のためのコミュニケーションができる。

ニワトリが鳴いてもいいとき

また別の観点として、「偉い人」や部外者が自由に発言しても良いとき、というのがある。

1つは、「良いこと」を言うときだ。これは、無条件に、良い。「ここの動きが良いですね」「速いですね」「きれいですね」「新しい機能気に入りました」「あざーす」など。そういう「褒め」はエンジニアのテンションが上がるので、言えるなら言えるだけ言ったほうが良い。特に、エンジニアが気を利かせて何かをやってくれたときというのは、本当に感謝すべきだなと感じている(言ったことを3倍にしてやってくれる人って、重宝ですよね)。

もう1つは、「長期的なビジョン」を言うときだ。(言い方に気をつける必要があるが)「一年後にはこうなってたいねー」とか「このプロダクトはこういう目的があってね」とか。「長期的なビジョン」を知りたいという開発メンバーは、マネージャーが思ってる以上に多い。単純にわくわくするので。そして、ビジョンを適切に伝えていれば、開発メンバーが「そんなこともあろうかと」と気を利かせた作りにしてくれることもある。

鳴く以外の、ニワトリの表現方法

偉い人と開発メンバーのコミュニケーションは、何も発言するだけではない。

ずばり、MTGに(勝手に)参加することだ。朝会にいれば、空気感もわかるし、「偉い人への報告」みたいなもの省ける。

ただし、MTGに参加しても基本的には発言しないのが重要だと思う。MTGというのは参加者が増えれば増えるほど、質が落ちるからだ。MTGは、ブタのための時間である。

もし気になることがあれば、後でチャットとかで「朝会で気になったのですが、◯◯って☓☓ですか?」みたいな非同期コミュニケーションで解決できる。

まとめ

最近考えていたことを、つらつらと書いてみた。

  • 「偉い人」や部外者が意見できる環境が健全だが、悪影響がある可能性がある。より良く伝えるためのテクニックがある。
  • 「良いこと」と「長期的なビジョン」であれば積極的に伝えたほうが良い
  • 「偉い人」や部外者もMTGに参加できる方が健全。ただし、その場では発言しない方が良い。

たとえシステムが落ちても“社内には”謝罪するべきではない理由。あるいは”反省”と”対策”にフォーカスしようという話

こんなことを書くと怒られそうなんですが、自分の一つのポリシーとして、システムが落ちたり障害が起きたりバグが発生したことについて、基本的に“社内には”謝罪しないことにしています(もちろん例外は度々あります)。

という概念は広まるべきだなと思っていて、紹介したいと思います。

こんなこと言うと、ビジネスサイドの人からは怒られると思うんですけど。。。

前提

  • 自分の勤めるJX通信社は、自社開発している企業であり、ベンチャー企業です。外注はしていません。
  • 自分の立場は、エンジニアですが、固い言葉で言うと中間管理職とも言える立場でもあります(チームリーダーとかっこよく言えるほど職責を果たせているとは思えないので、そういう言い方をします)

理由1:システムは落ちるときは落ちる。バグるときはバグる

最初から諦めていて申し訳ないのですが、まず第一に、システムは落ちるときには落ちます。バグるときはバグります。システムを落ちづらくしたり、バグりづらい開発体制を敷いたりすることはできますが、100%24時間365日落ちないシステムというのは基本的にはできません。(こういうことを言ってしまうと、仕事に対するスタンスとして当然不適切なのですが)

具体的な事例を出すと、僕みたいなポンポコリンより数百倍すごいエンジニアを集めたGithubでも、落ちますGithubは有償プランを持っていますが、それでも落ちます。AWSですら障害は起きます。

理由2:ほぼ落ちないシステムはあるかもしれない。けど、コストとスピードが見合わない

落ちないシステムを作るとしたら、たとえば次のような「品質担保」の段階が考えられるでしょう。次の例は、AWSを使っている企業が落ちないシステムを作るための話です。

  1. ソフトウェアが落ちても自動復旧する設計にする → 負荷が高まって、無理かもしれない
  2. オートスケールする設計にする → リージョン全体で障害が起きるかもしれない
  3. マルチリージョン構成にする → AWS自体で障害が起きるかもしれない
  4. ハイブリッドクラウドや、GCPなどその他のクラウドサービスを併用する

加えて、パフォーマンステストみたいなものを時間を取って行なうといった作業も必要になるでしょう。ソフトウェアまで踏み込むと、厳重なコードレビューをしたり、カバレッジ100%なテストなども必要かもしれません。

システムを他社に卸す企業ならまだしも、自社新規サービスやエンジニア数が限られていたら一層、これらはコスト的に見合うものではありません。要は、リスクマネジメント=いわゆる「程度の問題」です。

ただ、一つ考えておかないといけないのは、「もしこの障害が起きたとき、どう対応するか?」というのは検討しておくべきなように思います。

理由3:謝罪しても何も解決しない

謝罪をすれば責任者の溜飲は下がるかもしれませんが、それ以上に何も生産しません。責任者が怒ってなければ(“怒る”責任者じゃないことを期待しますが)、なお一層無意味な振る舞いです。

代案:反省しよう!

とはいえ、十分にシステムに対してやるべきことをできているとは思いません。やるべきことがないとも思いません。日々精進、日々改善です。

そこで代案として提案したいのは、謝罪しない代わりに、障害対応報告は必ず書いて反省しましょう、です(※そこに「申し訳ございませんでした」を書く必要はない)。

弊社の場合、次のような障害対応報告テンプレートがあり、それに則って書くようにしています。これは、システム障害にかぎらず、ソフトウェアバグに関しても使うことがあります。

# 障害概要 

# 発生原因 

# 対応内容 

# 再発防止策

自分の場合は「どういう調査をしたか」というのも書くようにしています。これは、また同じような障害が起きたとき、自分以外の人がその調査フローをなぞって切り分けできるようになるためです。

また、再発防止策は、具体的で、過剰な時間をかけずに一定の品質を担保し、直近取ることのできる策であることが特に大事なので、それを意識しています。

まとめ

  • 謝罪をするのはやめよう
  • 代わりに、反省をして、具体的な対策を考えよう
  • 日々精進

なぜ“まとも”なソフトウェアを作らなければいけないのか

私達まともなソフトウェアエンジニアは、まともなソフトウェアを作ろうとする。ソフトウェアエンジニアには、アプリのエンジニアだったり、サーバーサイドエンジニア、リサーチエンジニアなども含む。

まともなソフトウェアエンジニアは、テストコードを書く。ドキュメントを書く。CIも整備する。まともなクラス設計を考える。スケールするDB設計をする。ここでは、「まともなソフトウェアエンジニア」を「優秀なエンジニア」と定義し、「テストコードがあり、ドキュメントがあり、CIも整備され・・・」なソフトウェアのことを「まともなソフトウェア」と定義しよう。

つまり、優秀なソフトウェアエンジニアは、まともなソフトウェアを作る(※必要条件)。

まともなソフトウェアを作るのは、時間がかかる。テストコードを書けば、それだけ時間がかかる。クラス設計を議論しても時間がかかる。

なぜ私たちはまともなソフトウェアを作らないといけないのか

もちろん「まともなソフトウェアを作ってない会社に勤めたくないから」とか「単純に作るべきだと思うから」というのも理由としてあるし、実際それは正しい。「まともなソフトウェアじゃないと品質低くて提供できないでしょ」も正しい。けど、もう少し深掘りしながら、なぜまともなソフトウェアを作るべきかを考えてみたい。

私たちはまともなソフトウェアを作るべきで「ない」のか

まずは逆説的に、まともでないソフトウェアを作る場合のことを考えてみる。

まともでないソフトウェアはテストを書かなくていい。CIも整備しない。ドキュメントは書かない。クラス設計は適当。DBも逐次てきとーに作っていこうか。議論も不要。コードレビューもやめよう。

まともでないソフトウェアを作るのは、余分な時間をかけずに済みそうだ。まともなソフトウェアを作る金が100万円だとしたら、まともでないソフトウェアは30万円くらいで作れるかもしれない。

やったね! どうやら、まともでないソフトウェアを作るべきみたいだ。

まともでないソフトウェアの問題点

まともでないソフトウェアの問題点は明確だ。

まず、テストコードが書かれていない。テストコードのないソフトウェアの品質は良くないだろう。将来の改修でデグレ(過去、動いていたものが動かなくなること)を起こすかもしれない。試していなかったパターンでエラーが起きるかもしれない。

CI環境も整備されていない。つまりデプロイは毎回手動でやらないといけない。ミスが起きるかもしれないし、デプロイするたび時間がかかる。

レビューも設計もないので、コードの品質もひどい。それでは後から入った人が困るだろう。どんどんクラスが肥大化していって、改修もしづらくなるかもしれない。

まともでないソフトウェアの問題点の問題点

ここまではあたりまえ体操だが、もう一歩うがった見方をしてみる。果たして、まともでないソフトウェアの問題点は、本当に問題なのか?

テストコードが書かれてないと、どれくらい困るだろうか。人によって意見が異なるだろうが、自分の経験上、完全に一人で作っている場合や、運用を考えなくていい場合、テストコードがなくて困ることはあまりない(※完全に一人かつ運用を考えないというのは、かなり限定的な条件だ。つまり一般的には必要だと考えている)。要は、自分個人の記憶以上にスケールする必要がないとき、テストコードはなくても困ることは少ないと思う。

CI環境がないと、困るだろうか? これもサーバー規模があまり大きくなければ、正直あまり困らない。例えば、ssh して、git pull して、restart かければ良い。もしくは、自分の手元からそれらを自動化する簡単なシェルスクリプトがあれば、時間もかからない。

コード品質は、一人で作っているときであれば、気にしなくても短期的には困らないものの最たる例だろう。オレオレ設計は、オレの中で最大級にスケールする。

要は、短期的に一人でやる場合であれば、まともでないソフトウェアを作ってもあまり困らない、というのが正直なところなんじゃないかと思う(だから私含めてみんなサボるんだ……)。

なぜ、まともなソフトウェアを作るべきなのか

ここで「なぜ私たちはまともなソフトウェアを作るべきなのか」という疑問に対する私個人の答えを言うと、チーム開発を円滑にするためであったり、長期的に運用するため、ということだ。

「チーム開発を円滑に」というのは、今現在一人で作っている場合にも当てはまる。「長期的に運用」というのは、作り始めでも当てはまる。本当に今作っているソフトウェアを成長させたくて、人を増やしてチームを大きくしたくて、一年後もコードを書いていたいなら、やっぱりまともなソフトウェアを作るべきなんだと思う。そして、「チームのため」という目的のためにこそ、あるいは「チームのため」という目的を意識しながら、まともなソフトウェアを作るべきであり、まともなソフトウェア開発は、チーム開発に還元されるべきであると思う。

逆に言えば、まともでないソフトウェアを作ろうとしているのであれば、それはチームを大きくしたくないということであり、今後運用したくないということだと思う。

何故こんな疑問を書いたか

冒頭に言ったとおり、まともなソフトウェアを作るのは時間がかかる。まともでないソフトウェアは時間がかからない。(本当に優秀なエンジニアは、まともなソフトウェアを短時間で作るだろう、というツッコミは置いておく)

まともなソフトウェアを作りたいが、実際のビジネス要件は「早く、早く」であることも多い。そのためには単純に、テストやCI、ドキュメント、設計に掛ける時間を削ることもできるだろう。けれどもそれを安直に受け入れていいとは、どうしても思えなかった。

裏返して、ビジネス的視点で考えたとき、「僕がまともなソフトウェアを作ろうとするのは、どう正当化できるだろうか?」という疑問があった。だって自分が経営者だったら、速く成果物を作る人を評価するでしょ?

そういったバランスの中で、「なぜまともなソフトウェアを作らなければいけないのか」を考えることで、適切に“まともさ”にこだわることができるんじゃないかと思った。

まとめ

  • まともなソフトウェアを作るのは時間がかかる
  • チーム開発や運用を考えるならば、まともなソフトウェアを作るべきである
  • というか、「チーム開発や長期的な運用のため」を意識して、まともなソフトウェアを作りたい

補遺

こんなことを書くと、「経営者はまともなソフトウェアを書かせろ!」とか「おいあいつまともなソフトウェア書いてないじゃないか」とか「まともなソフトウェアはわしが育てた」とか言っているかのごとしですが、そういうのは全くないし、一切の皮肉を含んでいません(汗 あくまで、自分が開発する上で何考えないといけないんだっけ、っていう思考の出発点のつもりです。

ちなみに自分がいるプロジェクトは、テストコードがあって、後からジョインしたら大変助けられたパターンです。