「仕事に疑問を持ったことはないか?」という問いは、全く無用な質問である。

f:id:ebabababa:20170710011339j:plain

先日、大学の講義への出席として投稿する、外部講師の質問に返答が帰ってきた。

質問1

今回は既に決まっているメンバーとのチームビルディングでしたが、チームを構成する際の人を集める方法と、人の選び方を教えていただきたいです。

質問1への返答

メンバーの選び方ですが、一番大切なのは Goal を明確に理解すること、それを達成するために何をしなければいけないのかをある程度の粒度で決めること、やるべきことの作業量を見積もることです。

もちろん、これを Leader 一人でやるのは難しいです。 似たような Project の経験者なり、Project の Key となる知識を持った人などに相談しながら作ると良いと思います。

必ずしもその人たちが Member になるということではないです。

あくまでも Planning の Phase と考えてください。 実際の会社では Project のWBS や Ganntt Chart などは過去の Best Practice といったところから Copy してきて、そこから修正していくケースが多いですし、効率的です。

ここまでくればどのような人が Goal 達成に必要か、それぞれ何人必要かが見えてくるはずです。

現実には予算が足りずに十分な Resource を確保できない、Skill の高い人ばかりを集められないなどの障害がでてきますが、Plan に立ち戻って実際に確保できた Team で達成する方法や手段を考えるなど何度か繰り返す必要がでてきます。

もちろん、Team の Member を確保したり予算を増やすなど交渉することも含めてです。

質問2

やはり開発をする上での目的とは別に、その会社もしくは集団で共通の”ゴール”という、目的をさらに抽象的にした、根本的な上位の目的を持っている、いるべきだという考えには僕も全く同意見です。

そして、そのゴールはすべからく人間を中心に置いたものであるべきです。ですが現在の日本ではこのゴールに"金"を中心に置いた開発・会社が幅を利かせています(e.g. DeNAサイバーエージェントなどソーシャルゲーム・アプリ開発界隈)(これは NetflixSpotify など海外のソフトウェアが好きな日本社会に反感を持つ人間の思い込みかもしれないですが)。

ここで先生に聞きたいのは、このソフトウェア開発発展途上国における日本において"人"を中心に置いて開発をしている企業です。

このことを人に話すたび、返答は「起業しろ」だの「働けばわかる」などばかりですが、このような綺麗事を持つ企業が果たして本当に存在しないのか知りたいのです。

質問2への返答

すでに大きく成長した企業であってもベンチャーで合っても基本は投資家・株主が投資したお金を運用して事業を行うことで利益をうみだし成り立っています。

あなたが投資家だとして、お金を運用することで自分の資産を増やそうとします。堅実を思われる運用方法は預金貯金です。

では何処かの会社の株を買う、ベンチャーに投資するという選択肢を比較するとき何を考えますか?

どちらが運用利率が良いかです。 そうすると、経営者は銀行などの市場金利よりも高い還元が出来る事業を行うことが期待されます。

なので目的の利益を(さらには利益率)を達成することが最優先です。

個人的な意見ですが、日本の株主は会社が成長し株価が上がることなどを長期的に考えるケースが多いですが、海外やベンチャーキャピタルはもっと短期的に利益を見ています。

これがお金=利益にこだわる理由の大きな物です。 (経営学などの講義を聴いてみてはいかがでしょうか?)


もう一点考えなければいけないのは事業の成熟度です。 これから立ち上がる市場への先行投資と、確率した市場での投資に対する Return とでは違います。

前者は核となる技術を確立させたり、市場の成長などを指標にしながら利益が少なく(でなく)ても投資するという価値はありますが、後者は投資に見合うかそれ以上の Return を追求します。

会社の年齢(?)ではありません。、あくまでも Market です。

TeamBuilding の Stage とは違いますが、4 つの Stage で考えると 立ち上がったばかりの Market では、その Market がどのくらい成長するのかが重要になります。

次の Stage では成長している Market の中で自分の会社がどのくらい Share を伸ばせるのだろうかが重要となり、3 つ目では 投資対効果 利益率などが重要となります。

最後の Stage では利益をあげながら、良い Timing で事業を売却したり撤退し、次に再投資することを考えることも多いです。


では人は重要ではないのかというとそれも違います。ベンチャーなど若い企業ほど個々の人の能力に左右される部分が多いです。

ソフトウェア開発では海外の方よりダイナミックな動きを感じますが、人という観点でみると、日本より流動的です。

給料の良い仕事があれば Project の途中での移ってしまったり、利益が出ない事業や Project はすぐに止められたりということです。

みなさんの世代の人たちの考え方は変わっているかもしれませんが、日本の Software Engineer の方が会社や組織、仕事に対する Loyaltyが高いように感じています。

その部分の強みを生かせないものだろうか と考えています。

まとめ

どうにも説明不足なのか「"人"を中心に置いて開発をしている企業」に正しく返答してくれなかった。

おそらくは僕の意図を理解しきれず、苦しい回答をするしかなかったためこのような返答になったのだろう。

僕が質問したかったのは “人"を中心に置いて開発したソフトウェア、を作っている企業なのだ。

つまりそれはユースケースが人の生活や行動に基いているソフトウェアであり、つまりそれはコンテンツを楽しむ上でその抵抗や障害を取り除くようなサービスである(e.g. Netflix, Spotify)。

そのソフトウェア(サービス)が日本に存在しないことは明白で、在ったとしたら既に使っているか、もしくは僕も知っていて、もっと使われていると思う(もしくは経営や表現で失敗しているかもしれないが)。

そこで実際にサービスはなくとも、そこを指針として捉えている企業ぐらいはあってもいいのではないか?という動機で質問したのだが。

ひとつストローマン的な視点から見ると、どうやらマーケティングにおいては、"人"とは資源でしかないようだ。

なるほどそういった神のような考えを、大審問官的にいえば「悪魔と手を組んだ」考えを持った人間がアイデアを出せば、"人"を中心に置いたものは絶対に作られないだろう。

いや、結局厭世的な意見でまとめてしまったが、決して彼らが低能であるとかそんなことを言いたいのではない。

同じ資源でより良い開発を、つまりもっと人の役に立つ開発ができるのではないか?というのが僕の意見だ。

ソフトウェアエンジニアになりたい学生の糞の垂れ流し

 日本人は欧米諸国と比べ形而上的なものより、形而下のもの、実存を求める傾向が強い。これは22年間日本で生きてきた人間の悪い思い込みかもしれないが、しかし僕とて日本人であり、デザインだけの話を聞くとやれ「ポエム」だの「実際のところ何ができるんだ?」という思考に陥る。もちろんこの考え、実存を求める考えは間違っていない。実存を産み出すことができる能力は力だ。石をパンに変える奇跡は現代の人間に必要なのだ。

 f:id:ebabababa:20170627041807j:plain

 しかし間違わないで欲しいのは結果は操作できるものではない、結果は結果でしかないということだ。結果の上には手法があり、手法の上には目的がある。目的のさらに上には…僕はここに人類の発展があると思う。つまり全ての人間の創り出す結果はすべからく人間の発展に基づいたものである。というのが僕の持論だ。

 人間がみな利他的な目的を持った存在であれば、上記のような思考を得る必要はなかったであろう。しかし実際は、JASRACが不当な著作権料の申し立てをしたり、電通がアニメの制作費を差っ引いていたり、資本家が偏った利益を出しているのが現状だ。昨今なぜくだらないライトノベルが頻繁にアニメ化しているのか。なぜくだらないソーシャルゲームが作られているのか。なぜくだらないコピーアプリが作られているのか。それは投資に対して十分に、安定的に利益が出るコンテンツがそれぐらいしか無いのだ。結果くだらない作品を作るルーチンが発達し、高度な技術・デザインによって創作された作品は淘汰される。小銃を持たせて戦わせても大して戦果が出ない、なら多くの人間に竹槍を持たせよう。というのが資本家達の考えなのだ。今に枯れた土地になるだろう。資源に乏しいこの国では特に。

 なぜこのようなルーチンが発展してしまったのか。現代の超時間の残業に晒されている会社員達はまさに神風特攻隊だ。資源も文化も技術もドクトリンもない。ならば我々はどうやって戦果を上げるのか…?今までのパンの水準を落とさないためには命を削るしかないのだ。

 とはいえ深刻な経済破綻に発展してないところを見ると、この日本の中にいる一部の天才達の影を感じずにはいられない。しかし我々は彼らに甘んじてはいけない。時代を動かすのは天才だが、時代を作るのは我々凡人なのだ。問題は我々は彼らに追従しようとしていない。利己的な目的に基づいている点であると言えよう。

 我々が努力不足である、という点を問いたいのではない。ただ我々は少し自分のことを考えすぎなのだ。JASRACにしても、電通にしても、高品質の作品を作るルーチンに投資していれば、そこから産まれる作品が世界からの評価を集め、投資する側もされる側も今よりずっと豊かになれたというのに。最新鋭の国内3Dアニメーション映画が、映画館で見るより早くストリーミングで再生できることに喜びと悲しみを感じる。

 現在僕は修士1年だが、学部4年の際に大手IT企業に対し就職活動していた。僕の実家は裕福とは言えず、研究に費やす熱意もなかったので、みなさんのご多分に漏れず、早く実存を得たかったのだ。くだらない同じような話を1・2・3回と繰り返すと4回目ぐらいで終わる糞面白くない行事だ。しかし僕は全ての就活に失敗し、現在修士1年である。

 ただ僕が唯一許せなかったのは、深く考えなくなり、成長を失うことだった。午後も大分過ぎた割にすっかり元気を保っている彼らは、最後の面接官だ。一目見ただけでわかる。彼らは既に、厭世、停滞、閉塞感、全てを経験し、そして抜け出せず、諦め、人事の上層部という地位に立っている。上場企業のベテラン人事で、妻と子もいて、一軒家に住んでいて、絶賛人生下り坂。このような、一体何が楽しくて生きているのかわからない人の下で働くことだけは、いや例えこのような人間の下で働くとしても、今ある微かな思考と成長だけは失いたくなかった。

 とは言え私も自分の能力の限界を感じつつある。自分が本当に満足できる、自分より少し能力が高い人間と一緒に働ける現場にありつけはしないだろう。文理不問の現場でデザインもドクトリンもなく、思考を捨て死の床に向かって特攻するのだ。しかし、今この時の場末に書く糞の垂れ流しのような青春ポエムぐらいはまともでありたいと願う。

HerokuでRedisを使ったら失敗した

この記事は決してHerokuでRedisを使うんじゃない!という話ではない。

だがHerokuで立てたことによって失敗したことは確かである。

今日、大学の実習課題で制作したWebアプリケーションを聴者の方々、およそ40名に使用させたのだが、しかし僕のHeroku上のSinatraで書かれたpumaはすぐに500を返すだけのサーバーになってしまったのだ。

結果、課題のシステムの背景や設計を細かく練ったにも関わらず、聴者は低評価を付け私はチームメンバーに悔しさを与えることしかできなかった。

一体何が起こったのか

端的に言えばRedisの最大クライアント制限に引っかかったのだ。

Redisのクライアント制限に引っかかると、その後新規にクライアントを作ろうとしても全てエラーとなる。結果 Internal Server Error だ。

Redis Document: http://redis.shibu.jp/admin/config.html#confval-maxclients

以下に絶対に真似してはいけないし失敗するRedisクライアントの生成コードを記述する。

module Whisper
  class App < Sinatra::Base

    ...


    def redis
       @redis ||= Redis.new(:url => (ENV["REDIS_URL"] || 'redis://127.0.0.1:6379'))
    end

    ...


  end
end

Sinatraアプリ上でRedisを呼び出すときにこういう書き方をしていた。

まあAppクラスのインスタンスが残っていれば @redis は再生成されずに、シングルトンのように扱われるし、扱って欲しいというのが僕の考え。

Redisのクライアント上限が20だというのはデプロイ開始時点で承知していたのだ。

しかし実際はこの記述の仕方では毎度インスタンスを生成し続け、一方でRedis側はセッションを最低30秒は保つようにしているため、30秒以内に21回のリクエストが発生すると500となる。

あまりにも貧弱なサーバーコードを書いてしまっていた。

自前である程度実行テストはしていたのだが、短時間で一気にリクエストを送らなければ発生しないため気づかなかった。

しかし、Redisの管理者画面からRedis Clientのコネクション数は確かめられて、殆ど自分か他二人しかアクセスしないページで、不自然に10のクライアントが生成されていることがわかっていても「pumaがスレッディングしているのかな…」と違う推測で理解してしまっていた。

pumaが複数スレッド立てていたとしても最大16個立てていたら1スレッドに対して2つのクライアントを立てるのでそれも落ちるというのに…

ではどうすれば良いのか

Rackサーバーから扱われる上記の Sinatra::Base クラスはリクエスト毎に初期化される。(推測だが)

それもそうだ、でなければ他のリクエストに対しても500を返すようになってしまうだろう。(もしくは何も返さない)

そのため、Sinatra::Base クラスの外側に Redis Client のシングルトンメソッドを設ける。

module ReadCache
  class << self
    def redis
       @redis ||= Redis.new(:url => (ENV["REDIS_URL"] || 'redis://127.0.0.1:6379'))
    end
  end
end

module Whisper
  class App < Sinatra::Base

      ...

      def redis
        return ReadCache.redis
      end

      ...

  end
end

これでHerokuは最大2クライアントしか生成しなくて済むようになった!

違う、そうじゃない

事前にこういった問題を検知するために負荷テストをしよう

これが本題。

結局のところ今回の知見としては「負荷テストをしなさい」という点に尽きる。

特にRedisのクライアント数が小さく制限されているとわかっている時などは重要だ。

後モンスターとコーヒーで脳をブーストしているときも。

正直 Sinatra や HTML / CSS / JS のコードは脳味噌を使わなくてもかける。

多くのプログラムを生成したところでそれはソフトウェアデベロップメントでなく、プログラミングをしただけであって、プログラミングができる=エンジニア とは呼ばない。それはプログラマである。

エンジニアとは…ソフトウェアエンジニアとは、ソフトウェアエンジニアリングの原則に則って、設計から開発、点検、テスト、評価までをする人のことを言うのだ。

Definition: Software engineer - Wikipedia

今回のケースで私は点検はしたがテストを怠ったのだ。ついでにいえば脳味噌を使ってないプログラミングをしてしまった。しかし人間誰しも完璧なものを作ることはできず、完璧に近づける行動しかできない。

そこで、完璧に近づける方法としてテストがあり、今回の負荷テストを行うためのツールとして代表的かつ効果的なのはこれだと思う。

loadimpact.com

というのも、ちゃんと500が出てくれたのだ。私はすっかりこのサービスに心酔してしまった。課金してもいい。

f:id:ebabababa:20170620215948p:plain

500が出ればログが出る。ログが出ればバグがわかる。

$ heroku logs -n 1000 | grep Redis
2017-06-20T10:14:58.371874+00:00 app[web.1]: 2017-06-20 10:14:58 - Redis::CommandError - ERR max number of clients reached:

f:id:ebabababa:20170620220410p:plain

バグを直せば200が出る。先人達が築いた「エラーがきちんと出る」というソフトウェア設計に敬意を表する。

開発物: github.com