島までは遠い 〜サークルアラウンド株式会社代表佐藤のブログ〜

佐藤正志@サークルアラウンド株式会社のことが少しわかる場所。プログラマーを育てるトレーナーとして、現役のソフトウェア技術者として、経営者の端くれとして、想うことをつづる。

「モデルの中からPOROを呼び出すのはどの程度認められるのか」気になります

はじめに

tech.medpeer.co.jp

この記事読んで思ったことを誰にともなくコミュニケーションしてみたくなったので書いてみます。当該の記事はリファクタリングの考え方としてとても好きです。その一方で過去私がとても苦しんだ事と同じ課題(もはやトラウマみたいな)を感じたのでアウトプットしてみたくなりました。

私の感覚

長くなるので後の方に色々細々した気持ちを書きますが、今の私はモデルのリファクタリングについて下記の記事をかなり重要視しています。その観点で当該のサンプルをリファクタリングするとどうなるかを書いてみると良いと思いました。

techracho.bpsinc.jp

上記記事に従うと、今回の場合「処理が複雑になった(という前提ですよね?)」と考えてServiceを採用するか、「あるユースケースにおける保存処理に介入する」と考えてDecoratorを採用するのが妥当な気がします。というわけで二つ書きました。そして私ならこれらの二つのどちらかがシックリくると考えて、元記事でのリファクタリング結果には意見を提示すると思います*1

Serviceを採用した場合

class Message < ApplicationRecord
  has_many :mentions
  belongs_to :creator, class_name: 'User'
  belongs_to :channel

  def here?; end # 省略
  def channel?; end #省略
end

class MentionNotifier
  def self.call(message)
    self.new(message).call
  end

  def initialize(message)
    @message = message
  end

  def call
    ActiveRecord::Base.transaction do
      return false unless @message.valid?
      @message.save!
      create_here_menthin if @message.here?
      create_channel_mention if @message.channel?
    end
    @message
  end

  private

  def create_here_mention
    members = @message.channel.members.active - [@message.creator] # これはMessageのメソッド化しそうですが、本題とはずれるのでこのまま
    create_mentions(members)
  end

  def create_channel_mention
    members = @message.channel.members - [@message.creator] 
    create_mentions(members)
  end

  def create_mentions(members)
    members.each do |member|
      @message.mentions.create!(to: member, chennel: @message.channel)
    end
  end
end

# 使い方(create アクションの中の想定)
message = Message.new(params)
MentionNotifier.call(message)

Decoratorとしての切り出し

class Message < ApplicationRecord
  has_many :mentions
  belongs_to :creator, class_name: 'User'
  belongs_to :channel

  def here?; end # 省略
  def channel?; end #省略
end

class MentionNotifier
  attr_accessor :message

  def initialize(message)
    @message = message
  end

  def save
    ActiveRecord::Base.transaction do
      return false unless @message.valid?
      @message.save!
      create_here_menthin if @message.here?
      create_channel_mention if @message.channel?
    end
    @message
  end

  private

  def create_here_mention
    members = @message.channel.members.active - [@message.creator] # これはMessageのメソッド化しそうですが、本題とはずれるのでこのまま
    create_mentions(members)
  end

  def create_channel_mention
    members = @message.channel.members - [@message.creator] 
    create_mentions(members)
  end

  def create_mentions(members)
    members.each do |member|
      @message.mentions.create!(to: member, chennel: @message.channel)
    end
  end
end

# 使い方(create アクションの中の想定)
message = MentionNotifier.new(Message.new(params))
message.save

モデルの中からPOROを呼び出すのはどの程度認められるのか

「今回選ばれた例が通知をする処理だから上記のような形の方がシックリくるのではないか」

と思われてしまうと本題と外れてしまうので章立てしました。私がRailsでコードを書き始めて当初悩んだことの一つがこの「モデルの中からPOROをバンバン呼び出すのはアリなのか」ということなんです。

私にとってJavaの業務系でのコードのスタイルがキャリアの初期にあった為か、POJO を中心とする書き方が身についており、肥大化するモデルの処理や、通知などの内容は元記事のコードのようにモデルの中からPOROを呼びたくなっていたんです。ただ、ロジック層に入ってPOROから(ActiveRecordに強く縛られた)モデルを呼び、さらその中で業務に関連したPOROを...と呼ばれるのが不自然に感じられていたんですね。

そういう中で出会ったのが先に紹介した肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)の記事です。この記事は悩んでいた私に一つの考え方を指し示してくれました。「基本的にModelを渡す形で良い」という事です。この記事に出会ってからは私が抱えていた悩みはスッと晴れました。手本とするのに適切であると思っています*2

ただ物事には例外がつき物なので「〇〇なケースでは認めて良いのでは?」というのもありそうです。私だとSTIしている複数のクラスからそれぞれの型に関連したPOROを生成させるメソッドを作りたいと思うことはよくあります。これは認めても良いかもと感じています。

そんな私が今回の記事を読んだ時に「あれ?私の過去の悩みって結構無駄だった?」なんて変な汗が出てしまったのでした(笑) というわけで、この話題について多くの方々がどのように考えていらっしゃるのか大変興味があります。もしも何か良い指針があれば私もそれを知りたいのです。

おしまいに

特にRailsでは慣習や大勢のパターンに合わせた書き方を強く推奨することで、多くのプログラマーがプロジェクトを移動しても活躍しやすいという土壌があると思っています。少し前にも「Serviceクラスをどのように書くべきなのか」などの話題があったりしましたね。こうやって「xxxなケースはyyyな解法が概ね良い*3」という事が積み重なってより良い開発をお互いにできる気がしています。ということもあり「私はこうかなー」というのを書いてみました。

また、スルーしてしまいましたが元記事の主題であるサービスクラスの書き方については、下記に倣っている様子なので「ですよね〜」と思って拝見していました*4techracho.bpsinc.jp

*1:開発の仕事の中でレビューする際に、私個人の哲学を押し付けて良い場合は限られていると考えています。だからこういうシーンでは大抵自分の意見を提示してみてコミュニケーションを取ります

*2:自分ところのトレーニングでもこの内容はよく紹介しています

*3:最高で無くても良く、一般的に皆がある程度納得できるものであれば良いというイメージです

*4:私だとメソッド名固定に強いこだわりは無かったりしますが

「Pythonによるはじめての機械学習プログラミング(ジェンガ本)」は機械学習の素晴らしい実践的なとっかかりを提供しています

はじめに

著者の一人、島田さんから献本いただきました。ありがとうございます。 知り合った頃は学生だった島田さんが、CTOとして大活躍して、今度は本まで出されるということでオッサン目頭が熱くなります。

GWの最初にとにかく読み終えておきたかったので初日の課題にしました。いつもならコードを試しながらなのですが、この本に限っては私が機械学習についてあまり知識がない為「手を動かす前にまず全体を読み切ってしまおう」という流れで、先刻読み終えたところです。厚さの割にスイスイ読めました。

勧めたい読者像

私の理解ではこの本は「機械学習に無知なシステム開発者に対する、素晴らしい実践的なとっかかり」を作るための一冊だと思っています。もう少し分解して対象者を書くと以下のような感じでしょうか。

  • Pythonを扱ったことがある、もしくは書かれたPythonのコードを処理を類推しながら読み進められる人。
  • 機械学習全般には詳しくないけれども、とっかかりになる道具の扱い方や解説を求めている人。
  • 機械学習ライブラリを扱った際に、どのようにWEBなどのシステムに組み込むのかのとっかかりが気になる人。

また、機械学習というと画像や文章など様々なところで応用がなされるものだと思いますが、本書で主に解説されているのは以下でした。

  • 教師ありデータを元にしたデータ予測(scikit-learn)
  • 自然言語解析を利用した類語検索や文書分類(Word2vec, Gensim, PyTorch)

このあたりに興味のある人は特に満足度が高いでしょう。画像や動画を処理したいような方は別の入り口から入る方が良いかもしれません。

全体的な章立て

大きく分けて4部で構成されています。

  • 第1章 Pythonによる機械学習プログラミングの準備
    • WindowsやLinuxなど各環境ごとのインストールから、Visual Studio Codeのデバッグ実行までスクリーンショットなど交えて丁寧に解説されていました。まだ試してはいませんが、これに沿ってやればそれほど苦しまずに環境を手に入れることができそうです。
  • 第2章 Pandasによる前処理とデータの分析
    • 機械学習を実際に始める前に行うべきデータの整理や基本的な操作について書かれています。こちらもかなりページを割いて丁寧に手法が示されていると感じました。
  • 第3章 scikit-learnではじめる機械学習
    • 機械学習についての導入から実践的な内容が記されています。詳しくは後述。
  • 第4章 GensimとPyTorchを使った自然言語処理
    • Word2vec を用いた単語のベクトルを使ってベクトルの引き算から単語を推察したり、文書を分類したりします。

読み進めて感じたこと

この本は最初から読み始めると第2章が長い割になかなか想像している内容が出てこない為、やきもきしてしまうかもしれません。 「何かデータを処理するいわゆる『機械学習っぽさ』を体験したい」という人は第3章から入ってみても大丈夫かもしれません*1。この章を読んでモチベーションを高めてから第2章でも良い気がします。ただし本書は「第2章も含めて初めて完成する」と思うので以下に記します。

3章の内容はとても良いバランスを突いています。

  • 機械学習についての概論的な導入、現場における課題感など
  • データとコードを使った具体的な処理
  • 実際にWEBのシステムに組み込むための考え方

まで通して説明されているのは、冒頭に私が書いた「とっかかり」を与えたいという本書の目的感によるものではないでしょうか。

また、折に触れてS3にデータを置いておく話が出るとか、サンプルがWEB-APIを作成するものであったり、解説にマイクロサービスという言葉が出ていることからも「実際のシステム開発の現場」について著者が強く意識していると感じます。

そしてこの第3章を読了すると、丁寧で多少冗長にも感じた第2章がいかに大切なものだったかが見えてきました。第3章に倣って実際に大量のデータを扱おうと考えると、第2章の話題を避けて通ることができないはずです*2。第3章や第4章を完成するための大きなパーツとして第2章が存在していると理解しています*3

第4章は大量のテキストが行き交う現代のシステムにどうしてもやりたくなる自然言語の処理について書かれており、興味深く読ませていただきました。単語ベクトルという考え方を導入することで言葉の相関を整理することができ、それによって言葉の類推的なことができたり文書を分類することができるというものなので、実際の自分のサービスでもやってみると有意義な結果が得られそうに思います。

本を読んでフムフムするより実際に稼働しているシステムの情報を使って手を動かした時、4章の評価が適切にできるような気がしました。

おしまいに

とりあえずこれまで「機械学習難しそうだしよくわからない言葉いっぱい出てきそうだからなぁ」と敬遠していたシステム開発者だったらこの"ジェンガ本"は一度目を通してみて損がない一冊だと思います。弊社トレーニングで機械学習コース作るときは教材にしたいです。

Pythonによるはじめての機械学習プログラミング[現場で必要な基礎知識がわかる]

Pythonによるはじめての機械学習プログラミング[現場で必要な基礎知識がわかる]

  • 作者: 島田達朗,越水直人,早川敦士,山田育矢
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/04/19
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

*1:このことは本書の「はじめに」にも書かれているそうですが私読んだはずなのにスコーンと抜けてました ^^;

*2:私だととりあえずGoogleDocsに貼って色々コネコネしてしまいそうですが、そんなことしなくていいんですね...

*3:私はまだ機械学習を利用したシステムを組んだことはありませんが、第2章のように「雑多なデータを扱いやすい形に編集したり、可視化して傾向を掴むなどすることは実際にシステムに組み込むよりも時間のかかる大切なプロセスだ」とのメッセージではないかと感じています

現場未経験のプログラマーが最初の現場で心がけると良さそうなこと

f:id:ms2sato:20190426001814j:plain

はじめに

弊社のチームトレーニングの中で伝えるようなことと、現場でチームを率いるリードプログラマーとして、経営者としてのいくつかの切り口を混ぜて「こうあってくれたら嬉しい」「こういうことを期待している」というのをまとめてみます。

適切なタイミングで質問できているか意識してほしい

  • 抱え込んで質問できない人
  • 考えないで質問してしまう人

どちらの極端も困るのです。ようするにバランスなんです。このあたりのバランスを崩している人は以下のようなことを日々言われているのでは無いでしょうか。

  • 「どうして相談しなかったの?」「早く聞いてよー」「今まで何をやっていたの?」
  • 「調べた?」「試した?」「読んだ?」

例えば私がよくやるのは「15分悩んで手が動かせない時には何か欠けている情報や経験があるから、誰かに相談したほうがいい」というようなことを伝えます。この15分は最短の時間で、この時間を相手の成長に合わせて伸ばしていきます。この手の「質問タイミング」について一緒にやっている先輩と相談するのは良い試みだと思います。

「実は適切に質問するのは結構難しい」と思ってくれたら一歩前進かもしれません。

「タスクの完遂」の前に「成長の機会」と捉えてほしい

「なんでもいいから言われたタスクをこなさないとクビになるかもしれない」 と思ってしまう瞬間があるかもしれませんが、行なっている業務がプログラミングであるなら(ロジックを書かない他の業務だと違うかもなので一概にそうだとは言い切りませんが)よほど酷くない限りそんなことはありません。もしもそういう強迫観念にかられて

「振られたタスクの内容と似たようなことをしているコードがないか、ソースを探してコピペする」

という行動をしていたら黄色信号です。もちろん参考にするのはありなのですが、理解しないでコピペするだけの行為ではいつまでも成長がありません。こういう行動を続けてしまうと、一年経っても同じことしかできない可能性があります。それはとても困りますよね。

タスクを完遂する中であなたの成長があることを期待されています。それはコードの書き方だけではなくて、質問の仕方や調べ方など、全方位的に可能性が広がっています。タスクをこなすごとにあなたのやれることが適切になっていっていれば、それはおそらく現場から望まれていることです。

ちなみにこういう「今望まれていることは何か」を発信してくれる現場とそうでない現場があると思います。こういう点についてコミュニケーションしてみるのは良いことかもしれません。

できれば長く付き合ってほしい

これは特に中小企業の経営者からは切実に望まれていることだと思います。その背景を以下に書いてみます。弊社は今の所この心配があまり無い状態ではありますが、気持ちとしてはこんな感じです。

あなたは最初からプラスの存在ではありません

多分大抵の人は気づいていると思いますが、最初からいきなり利益が出せるような働きができることなどまず無いです。もしも軽快にタスクがこなせているとすると、それは誰かのフォローや適切な対応の結果によるものでしょう。以下はその一例です。

  • タスクが「誰かによって」適切に分解されている
  • 適当なレベルのタスクが「誰かによって」選択されて担当させてもらえている
  • 補助的な知識の補足が「誰かによって」うまいことなされている

「誰かによって」と出てきていますが、端的に言うと「これを誰かがやってくれている時点でそこそこコストがかかっている」ということになります。だから自分がスイスイこなせている場合でもトータルでプラスになっているかは疑わしいのです。

マイナスなのにどうして置いてくれるの?

ちゃんとした経営者ならそこそこ長い目線で物事を考えています。例えばあなたが一年以上かけて成長した先に、これまでのマイナスを取り返してプラスになってくれることを期待しています。多くの経営者にとってこれは 投資 なんです。投資をして数年後に取り返す、ということを想定しています。

回収できないなら次は行えない

あまりに簡単に短期間で離脱されてしまうと、それまでかけたコストが回収できないので同様の施策を行うことに臆病になります。結果として「現場未経験の人を雇うのはやめよう」という判断になる可能性もあります。この事実をどのように受け止めるかは個人の自由だと思いますが、少なくともそういうことを知っていて欲しいと思っています。

もちろん本当にひどい現場もあるので、そういう場所は早く離れて正解だとは思います。

おしまいに

最初の仕事の現場は大切にして欲しいと思っていますし、雇用のミスマッチがなるべく発生しないことを切に願っています。成長して卒業して行くのは当然起こりうることだと思いますが、得るべき体験が得られる方が皆にとってハッピーかなと思います。

「状況に合わせて適切に情報が流れるのが良い組織ではないか」という仮説

f:id:ms2sato:20190411141726j:plain

はじめに

長すぎたのでブログ化

組織化について

基本的に組織化されている状態について多くの人が思い浮かべるだろう表現を書いてみると「トップからの情報がツリー状に伝達されることで効果的に末端まで行き渡るさま」だと思う。これはいわゆるトップダウンという山型の組織である理由だろうとも感じる。

表現を変えると「トップの意思の素早い全体反映に特化した情報伝達の形態」とも言えるかもしれない。

ただ、これについて多少のイメージの違いがあり「末端で起きていることの中枢への伝達」についても考えるべきではないか、というのが私の仮説である。

人体を参考に表現する

基本的に私たちは大脳で考え、行動している。頭で考えたことが手足に伝わり、体を動かしている。これは通常時の体にとってはごくごく当たり前の事だろう。

逆に通常ではない状況を考えてみる。たとえば熱したヤカンに触れてしまった時、たとえば尖がった針が指に刺さった時、危機的な状況があると体は大脳に情報が完全に届く前に反射を始める。それと意識する前に指を引っ込めるはずだ。

前者はトップダウンで大脳から情報が伝わっているが、後者は大脳での意識の前に小脳などで判断し行動している。危機的状況への対応とはこのようにショートカットして起こるべきなのかもしれない。

組織に戻してみる

これを実際の組織に置き換えると、順序を通り越して一気に判断まで持っていくことが必要ではなかろうか。その際「通常伝わってくる山型の経路をショートカットして直接判断できる存在まで伝達する」べきかもしれない。

私自身の場合だと、経営や営業からコードを書くところまである程度把握しているので*1、コードを書く現場で起きていることも自分の判断が行える。針が刺さったところを見せて貰えれば「どうしておけば良いか」ある程度責任を持って判断できると思う。

このような感じに2-3ステップすっ飛ばして「責任を持って瞬間的に判断できる」存在まで情報を伝えてしまうのは大事な気がする。特に何か問題が起きた時に「そのレイヤーではどうしようもないかも知れないが、他の人なら十分調整できる」という事は多数ある為だ。わかりやすい例を挙げれば「開発が遅れているけれども、営業が顧客と相談すれば期日を伸ばせるので、開発が残業地獄にならなくても済む」というような事がよくあるという事。

弊社について振り返る

今のところ自分は大脳と小脳を兼ねているので、基本的に会社の隅々まで意識を行き渡らせようとしている。以下のような事はそういう自分の感覚の発露でもありそうだと振り返って感じた。小脳としては指先が傷ついたりしていないかを常に確認したいのだ。

  • 必要そうな時に気軽に声かけしてもらうように*2して、なるべく早くその人と直接会話する。
  • 自分が帰るのは他のメンバーより早い事が多いが、出ていく際にデスクを回って声かけをしている。
  • なるべくメンバー全員が昼食を一緒にとるようにしていて、雰囲気が感じられるようにする。
  • オフィスで過ごしている際に自然に雑談している(これは意識していないので単純にキャラクターの問題だけれど、プラスに働いていると思う)。

どこかで小脳的な存在にバトンタッチする必要は感じていて、どのようにシフトしていくのかは課題でもある。

(おまけ)今後のことを考えてみる

人数が増えて、並行して進むプロジェクトが増え、書かれるコードが増えると、私の能力が会社のボトルネックになってしまうと感じ始めた。

実際最近コードレビューをメンバー相互にやって良い形に移譲したりしている。これはこれで正直不安な事もあって「どんなコードが書かれているかを自分が保証しているから自信が持てている」状態を捨てなければならないから。

多分「プロジェクトに責任を持つ存在がコードについても保証できる人である」というのは至極理想的な状態で、それを崩すのは本当は良い形では無いのだろう。弊社の扱うプロジェクトは規模が比較的小さいのだから、理想的な形を追っても行けるのでは無いかと思っている。まだまだ工夫の余地があるのだ。

今後今までよりももう少し人数規模が大きくなる想定で進んでいるので、私の今の仕事をうまく別の人に移譲するのは大事な事だけれど、スムーズなやり方を模索しないといけない。

こういうポジティブな悩みが発生しているのは良い傾向でもあるので、向き合ってうまく着地させたい。

*1:最近怪しくなってきてて課題の一つではあるが

*2:これ自体も色々と工夫が必要そうだけれど

一号社員齋藤の門出に向けて。もしくは最初の社員を雇う時に起きたこと。

f:id:ms2sato:20190323155727j:plain

はじめに

先週の3月15日に、いくつかの節目がありました。それについて記しておこうかと。 同日に短時間正社員だったメンバーががフルタイムになったり、契約社員だったメンバーが正社員になったりしています。何より大きいのは一号社員齋藤のサークルアラウンド卒業でした。

少し彼と私のことを残しておこうと思います。

出会い

実は入社かなり前から彼とは面識があり、もともと私の教え子でした。弊社の第3期は一人株式会社で、私はプログラミングの非常勤講師として外部の学校で教えていた時期があります。

ある日学校主催で海近くの施設でイベントがあると誘いを受けて参加したところ、そのイベントの中で出会ったのが齋藤でした。ちょっと色々とあって砂浜へ行くことになったのですが、私と齋藤が海岸のレジャーシートで荷物番をしながら酒を飲む、という構図になっていました。真夏の海辺で周囲はチャラい色黒のイケメンやギャルがいる中、青っ白い我々が飲みながら話している、という変わった状況です。

当時彼は就活を控えて今後の人生に悩んでいて、そんな話を聞かせてくれました。私としてはいくつか話をしたような気がしますが特に強く伝えていたのが「若い頃は全力投球したいと思えることにできるだけ取り組み、少し歳を重ねてから効率よく生きることを考えたら良いのではないか」という話です。全力投球の回数が成長に繋がると考えているので、若いうちからあまり「うまい生き方」を意識してしまうのは成長を止めてしまうのではないかという論旨でした。

その時はなにか判断のきっかけになるものが生まれればいいなという感じでおわりました。

JavaScriptゼミ

当時の私はJavaScriptにご執心だったため、学校の方でもJavaScriptの専門家として色々と教えていました。ゼミという企画を始めることになり、「佐藤ゼミを持って良い」という話が持ち上がりました。受ける人は学校側で選んでくださるということで、4人ほどの受講生がおり、その中の一人に齋藤も混じっていました。ちなみにこの時の受講生は優秀な2人と、まだまだこれからの2人くらいの構成で、齋藤はまだまだこれから組と私の中でイメージされていました*1

半年の期間で毎月私の講義があり、その間はSlackとgitでオンラインフォローをしていくという形式で進めました。講義の際には「プロとしてプログラミングをする私たちの心理」が理解できるような切羽詰まった課題を出したり、JavaScriptの特徴的な機能を講義形式で伝えて、それに即した課題を解いてもらうなど、かなり実践的かつ「手を動かす」ことを中心の私好みの形で運営したのを覚えています。

この年の最後に、非公式で私たちの卒業制作発表会を行いました。また、私の用意したいくつかの尺度からアンケートを行って「年間MVP」を決めたのですが、齋藤はそのMVPを獲得したのです。単純に能力が高いかということでは無くて、どれくらいの努力をして、結果成長が見えたかなどの切り口も用意していた事もありますが、少なくとも自分で簡単なシステムを作成することができるレベルまで到達できたことは大きな前進だったと思います。

のちに齋藤とこの時の話をした時には 「PHPを勉強してみてあまりプログラミングはできないなと思っていて、JavaScriptゼミで無理だったらプログラミングは諦めようと思っていた」 と語っています。確かに当初コードに関する勘はまだまだ無く、調べながら必死についてきている感じでした。

その晩の打ち上げ飲み会で私が 「ここのメンバーだったら困ったら相談くれればうちで面倒見てもいい」 的なことを口走ったらしいですが、当の私はスコーンと忘れていたんです。ダメな大人です。

入社のご提案

ゼミが終わってから数ヶ月して(ちょっとこのへん私の時間感覚が曖昧です)。「相談したいことがあるから時間欲しい」と呼び出されたので、新宿の居酒屋で飯を食べることになりました。当初「多分就活の相談で、紹介できる会社とか用意しておけばいいかな?」などと考えていたのですが、ちょっと話の流れが違う様子でまさかの「サークルアラウンド社に入社したい」という話でした。

正直私は面食らいました。とにかくその日は落ち着いて色々と情報を交換しようということにして「一人株式会社である弊社の現状」をとりあえず洗いざらい伝えてみて、そのリスクの高さを理解してもらおうと試みたんです。きっとビビって諦めるだろうと。 フリーランスをやったことある方ならわかると思いますが「一人を面倒見るのが精一杯で、とても他人の面倒など見れない」というのが大抵の一人事業主の実態だと思うんですね。

とりあえず「現状共有したから考えてもらって、二週間くらいしたらまた対面しよう」とその日はお開きにしたのです。ただ、その後のメッセージのやりとりが完全に「入社したら」が暗に枕にある内容ばかりで「あ、ヤバイこいつ本気だ」とまさかの私が追い詰められる展開。

従業員が初めて入社するということ

ここまで本気だと二週間待つまでもなく彼の意志は変わらないでしょう。私も受け入れを真剣に検討すべきです*2。まず弊社の当時の状態で、ある程度彼を受け入れるポジティブなポイントはありました。

  • 直前で私がとにかく受託開発しまくっていて、ある程度のキャッシュの余裕があったこと。一年程度は彼が一円も稼がなくても会社は潰れないと計算できたこと。
  • 受託開発の仕事は継続していたので、仕事がなくて困ることは暫くなさそうなこと。
  • 先のゼミの彼の成長ぶりを考えると、最短半年もあれば彼にある程度お金を稼げるようにしてやれると推察できたこと。

上記を組み合わせると 「最長一年間我慢できれば一人有能なメンバーが手に入るかもしれない。そうすれば会社は潰れない。」 という解に至りました。会社的には受け入れ可能という事ですね。

この準備を持って、2度目の会話は入社意思を確認して受け入れが約束された形です。

次にやったのは「会社に社員を入社させる際に必要なことを調べる」です。それまでの弊社は取締役がいたことはありましたが、従業員という存在がいたことはなかったのです。そして会社に社員を入れるには下記のようなことがポイントになる様子でした。

  • 事務所を持っている
  • 年金事務所に登録する(この為に事務所が必須)
  • あと入社前後で色々役所に登録しなきゃいけない(もう忘れました)

当時私はバーチャルオフィスで登記していたので、ちゃんとした事務所はありません。年金事務所に電話すると「どうしてもシッカリした事務所がなければ年金の登録は不可能」の一点張り。当時自宅が事務所にできない事情があった私としては、なにがしかの形で事務所が必要になりそうです。

この後色々とあって、最終的に高田馬場にある CASE Shinjukuさん のシェアオフィスに入ることを決めました。

2015年4月 入社以後

彼と私がCASE Shinjukuさんのシェアオフィスで一緒に活動を始めたのがここからです。 日中はシェアオフィスでもコワーキングスペースでも自由に使えるという事で、私たちはその日の気分で居場所を変えていました。とりあえず「先生」と私のことを呼んでしまうのを直してもらったり、Rubyを勉強してRailsチュートリアルなどやってもらったりしていました。git/GitHubを学んだ時にはそのまま勉強会を開いて成功体験を作ったり、女子の大学生をインターンで連れてきて教える練習をさせたり、私としては「辞めてしまわないように必死(でも必死さは出さない)」のような時間が続いていました。

想定通り半年もすればある程度書けるようになり、私の仕事の裏側で彼がコードを書いている状態も作ることができ、お客さんに半人前としてではありますが、認知してもらえるようになりました。初年度の年末には業務委託の方と一緒にシステムを仕上げて引き渡すところまではいけて、計画通りに成長を達成できたことになります。

私としてはそういう流れを後押ししつつ自分でもコードを書きつつ、会社の次のステップを探っていたりしました。結論として「資金調達がある程度必要」と考えました。たとえ売上が暫く立たない時期が来ようとも、彼が路頭に迷わない形を作りたかった為です。私個人はどんな状態でも生きていける自信がありますが、齋藤がそこに達していないのは間違いなく、会社が無くなる事態は避けたいというのが当時の心理です。

幸い CASE Shinjuku さんは事業を後押しすることを積極的にやられているシェアオフィスなので、資金調達に関する軽い相談も受けてくださいました。右も左もわからない私としてはこちらで支えていただいて初期のステークホルダーとの関係の持ち方など多数学ばせていただきました。この結果、金融機関からの資金調達、創業助成金の獲得など、会社の安定のためのキャッシュの獲得を行えたのは大きな幸運でした。

とは言えこの頃私は多くの時間をこれらに費やしたのでヘトヘトでソファに転がっていることも多く「佐藤さん死んじゃうよ?w」と心配されたりもしています。まぁ、必死でしたからね。

2年目以降

だいたい良い感じになったので、Dockerを学んでもらったり、お客さん先に露出していって最終的に私と立場をスイッチしたりとよく活躍してくれました。特に丁寧に真面目に取り組む姿勢から客先の評価がすこぶる高く、今回の退職を期に引き上げになる際には大変惜しんでいただけたそうで、コードを書く腕前もマインドも高い評価をいただけていたと思います。

弊社のトレーニングのトレーナーとしても自身が苦労してプログラミングを学んだこともあってか、初学者の方に寄り添う姿勢が素晴らしく、私よりも低くかがんで目線を合わせられるという「確固たる自分の居場所」を確立していました。彼の丁寧なサポートでコードを書けるようになっていった方が何人もいます。

私から学び取れるものはとことん取っていこうとしていたので、設計に関する勘所や、サーバーサイドのシステムの扱いはかなり継承されたなと思っています。

そして今

懇意にされている方が新規事業を興されるということで、最初に現場を牽引するエンジニアとして声かけをされたと相談を受けました。当初は弊社から業務委託でやれないかも探ってくれてはいた様子ですが、新規事業は片手間でやるようなものではないと私も合点しており、最終的に弊社を出て行く決断となりました。先に副業で次の現場で活動を始めていて、既に2人ほどのメンバーの面倒を見ながら進めているようです*3

私としてはもちろん痛手ではありますが、弊社のメンバーが成長し現場を牽引する立場に至ったことは大きな価値を生めたのだと自分を納得させています。将来リードエンジニアからCTOのような立場になってくれるだろうとも思っています。冒頭にも書いているように、最初から物凄くセンスがあるタイプではなかった彼が、努力の継続によってここまで至ったことは私にとっても誇れる存在です。弊社の文化を最も身につけた存在が、外で新たに文化を広めてくれると思っています。

下記のサービスを今後は盛り立てていくということでした。遠くから応援したいです。

sharekura.com

齋藤への大きな感謝とともにこのエントリを締めくくります。ありがとうございました。

*1:この優秀側にも思い入れのある人物がいたりしますが、それはまた別で語れればと思います

*2:酔った勢いとは言え約束したはずなので、覆すのはなるべくしたくはありませんでした

*3:実力もっとアップさせるのに弊社トレーニングで協力できないか?のような話も出ていたりいます

ITにおける警察と私たちの判断の乖離について

f:id:ms2sato:20190307162305j:plain

はじめに

最近の世間の動きを見ていると、下記のCoinhiveの利用者の逮捕や

tech.nikkeibp.co.jp

nlab.itmedia.co.jp

簡単ないたずらスクリプトのURLを掲示板に貼り付けただけでの補導、家宅捜索などが話題になっています。

japan.zdnet.com

私は法律の専門家では無いですが*1、一ソフトウェア技術者として行き過ぎた判断が行われていないかを危惧しています。

また、この問題を今の私がどのように受け止めて理解しているかを記しておくことは、この先自分自身が振り返った時に大事なポイントになりそうな気もしています。

私の考える3つの課題

A. 被害程度への理解についての課題

これは警察の担当者(令状を出す裁判所も?)が問題の程度を適切に判断していないと推察される為の課題です。

  1. (ブラウザの外で動作する)実行ファイルによるワームで個人情報を抜き出したり、ディスクの内容を破壊したりするような行為
  2. (一定の範囲でユーザーが守られているブラウザ内で動作する)JavaScriptでCPUパワーを利用する行為
  3. (一定の範囲でユーザーが守られているブラウザ内で動作する)JavaScriptで、ポップアップを連続で出す行為

1が最も甚大な被害(破壊行動、個人情報流出を引き起こす犯罪行為)で、3が最も軽微な被害(子供のいたずらレベルと呼んでいい)であると私たちソフトウェア技術者は認識すると思います。どうもこれらの差を適切に認識されていない節があります。1ならまだしも「3で補導される」「3で家宅捜索される」のはどう見ても行き過ぎであると私は考えています。

ここで2に言及しなかったのは次の「犯罪予見性についての課題」に関係するからです。

B. 犯罪予見性についての課題

「過失」という言葉と関係すると思うので、まずそれについて確認させてください。

過失という言葉を噛み砕いて表現すると「違法な結果を予見することができたにもかかわらず、対応を怠った」で良いと思います。

つまり、違法かどうかの判断が行えなければ過失は存在しないはずです。まだ何の判例もない内容について違法性を洞察することが難しいものは無数に存在すると思われます。このような難しいものについて「行為者に犯罪予見性があったに違いない」という判断が行われている節があります。Coinhiveは特にこの傾向が強いのですが、長くなりそうなので付録の方へ譲ります。

程度の差がありますが、以下2点は同じようなことを言っています。ポイントは「犯罪予見性の認識」の有無です。

  • 「一般のソフトウェア技術者でも判断が割れるものについて『犯罪である』との判断が事前に下されており、行為者が認識していた」というような前提で行動していると推察される事
  • 「一般人(ソフトウェア技術者に限らず)が特に犯罪視しないものについて『犯罪である』と行為者が認識していた」との判断が事前に下されている様子に見えること

今回訴訟にまで発展しましたが、有罪の判決が出てはじめて「犯罪である」との正しい認識が発生するはずです。時間軸が噛み合っていない事がわかると思います。

C. 逮捕までのプロセスにおける課題

この課題はこれまでのA、Bどちらかが適切であればおそらく発生しないです。しかしA、Bが適切でない方向へ判断された為「突然の家宅捜索」という形で現れてしまったと考えています。「(よくわからんがこれは重大な)犯罪行為だ!しょっ引け」という事ではないかと推察しています。

このプロセスはあまりに盲目的過ぎると思われます。ソフトウェア技術にある程度詳しい人間であれば、A、Bのような推察は容易にできるはずで「これはまだ強行して進められるレベルのものではない」と発信する事ができたはずです。そういった抑制の仕組みが逮捕までのプロセスに存在しないのは大きな課題だと私は考えています。

私が社会へ願う事

  • 国家権力を持っている側に、現在のソフトウェア技術に関して適切に判断できる素地を持っていただきたいです。
  • 逮捕までに「より適切に判断できる専門家の見解を求める段階を設ける」など誤った方向へ進んでしまわない抑制力を持っていただき、無闇に逮捕しないでいただきたいです。
  • 誤認と認められた際に、行為者とされた方が失った名誉や仕事上の不利益を回復する仕組みを作っていただきたいです。

[長い付録] Coinhiveの違法性の難しさ

Coinhiveがマルウェアであるのか?

おそらく以下の記事などが実情を知るのに良さそうなのでリンク入れておきます。

www.itmedia.co.jp

今回の内容が広がった際にIT技術者の中に様々な見解があったという背景を示しています。海外でのアンケートを抜粋します。

上記のスレッドを追うと、とても興味深い発言を追うことができます。ポイントをいくつか拾って要約しました。論点としていくつもの切り口があると理解できると思います。

  • ユーザーの同意の取り方によって違う
  • 広告とどちらにするか選べる方が良い
  • CPUパワーの利用程度によって見解が異なる
  • マルウェアではあるが、好ましい
  • モバイルでないなら許せるが、モバイルでは動かしたくない

マルウェアとの差異

マルウェアとは|マルウェアの脅威とその対策

マルウェアについて改めて調べてみると、Coinhiveはウィルスやワームの一種であると判断された可能性があります。感染もせず、自己拡散もしないけれども(WEBサイトを閲覧中に背後で動き、閉じれば消えて無くなるため、どちらも行えない)、 CPUリソースを借用する という点です。また、他のマルウェアのように情報の盗み出しを行うものではない為です。

「ユーザの意図に反する、有害な作用を及ぼす」とはどういったことなのか

がやはり焦点になるのでしょう。

広告との差異

そもそもの経緯から考えるとCoinhiveは以下のような課題を解消すると目されていました。広告同様に売上を発生させながら、広告に比べてより優れたユーザー体験を提示できる可能性があるのです。

  1. 現在のWEBサイトは多数の広告に支えらえてビジネスが行われている事が多いです。
  2. 1のため、ユーザーに対して以下のような問題が発生しています。
    • 見たくない広告を見せられる心理的負担
    • (見たくない動画などによって)リソースが利用されるという浪費
  3. Coinhiveを理想的に利用する事ができれば、ユーザーから心理的負担を取り除き、以下の1点だけを受容してもらう事でビジネスが行える可能性がありました。
    • リソースが利用されるという浪費

残念ながらCoinhiveはサービスを終了してしまいましたが「今後同様のサービスが出る可能性についてどのように対応すれば良いのか」という岐路に私たちがいるような気がしてなりません。ひいては「私たちの社会がまだ見ぬ新しい技術についてどのように適応していくべきか」という課題も提示していると思います。

私が想像する事

今後も広告の代わりになる何かを発明した際、きっとCPUやメモリなどのリソースを利用して何かをする事が引き換えに必要になると推察されます。その利用程度をガイドラインとして定めるなどすると、世界が平和になる可能性があります。

例えばブラウザが抑止能力を持ち、広告代替に対しては行き過ぎたリソース消費を抑えるような仕組みが検討できると良いのかもしれません。

海外でも話題に

JavaScriptの作者さんにまで現状が届いていて「日本に来て、専門家として話をするかもしれない」とまで言ってくださっています。

www.itmedia.co.jp

おしまいに

「権力を持っている側は、その力が適切に行使されているか自身を監視する能力も持つべきではないか」と強く感じました。私としては今の見解をここに残す事ができて満足しています。少なくとも10年後、20年後社会がどのように変わったのかの差分をこの件との比較で行えると思うのです。

同時に「私にできることは何だろうか」と引き続き考えてみようと思う次第です。

*1:間違ったこと書いてたらそっと教えてください

KPI項目の安易な決定は危険と思っている話

f:id:ms2sato:20190110005130j:plain

はじめに

年明け一発目ですね。本年もよろしくお願いします。

弊社では私が忘れ去らなければ「通年KPT」というのをやります。毎週週報をKPT形式でSlackに流してもらってコメントしているのですが、年明けくらいは年間の長いスパンでKPTするのも良いだろうという感じです。今年は少し丁寧にやったので

  • 社員個別にそれぞれKPT形式から広げつつ色々聞かせてもらう
  • 社員メンバーと私でチーム全体のKPTを行う

というような大きく分けて二本立て。私の半日使ってしまいましたが、かなりいい場ができたと思っています。*1 その中で数値目標、KPIについて話した内容を残しておきたかったのでブログっておきます。

重要であることは疑いない、けれど安易に決めれば良いものではない

きっかけは「トレーニングの受講生獲得人数など、数値目標を立てたらどうか」という意見が発信されたことです。

おそらく経営の業績にこだわる人は大好きな話ではないかと思うんです。目標たる数値があり、それに向かうための戦略を立てたりされてますよね。ただ私が知っている『よくある結果』を思い返してみると「KPIを導入するならば、どの項目にするのかを多角的に判断した上でなければいけない」ということがあります。

トレーニングでの例

少し考えてみましょうね。

受講生獲得人数

例えばですが「トレーニングの受講生獲得人数を2018年比120%を目指す」などとしそうですね。仮にそう決めたとしましょう。当然ですが目標を決めたなら本気で達成しに行かなければ絵に描いた餅です。そうすると以下のようなことが発生すると思うのです。

「この人、弊社トレーニングを受けるタイミングじゃないな...。」
「でも、ロストすると今月の目標達成が難しくなるなぁ。」
「とりあえずプッシュしてトレーニング始めてもらうようにするか。」

この結果、適切なタイミングではない人がトレーニングを受講してしまいます。途中で続けられなくなってしまったり、そうでなくとも満足度が下がったりなどするはずです。少なくとも満足度低下は2018年よりも確実に増えると推察されます。これでは本末転倒だと思うのですよ。

顧客満足度

では逆に顧客満足度を上げていくことを考えようとすると、すると満足度というのは「期待値」によってずいぶん変わることが壁になります。また、おそらくアンケートをとって集計するかと思いますが、受講した人であれば低い評価は出しにくいバイアスの大きなものであると想像できると思います。

継続期間

大抵の商売であれば、サービスの利用期間は良いサービスの指針として素晴らしい項目だと思います。

ですが、教育サービスにおいては別です。まずシンプルに考えて、短期間で高い技術を身につけられるのに越したことはありません。もしも長い期間受講するということであると、その内訳として考えられることの中には「なかなか成長できない」「受講生が依存して自立できない」のようなネガティブな理由を内包しています。

逆に、月額料金で行なっているので「その期間顧客が与えられている価値に納得してくれている」とも取れます。さてこの数値をどのように評価するのが良いのでしょう。

もちろん「ネガティブな事は起こり得ない」と切って捨てる手もありますが「目標ギリギリ達成させなければ、更新してくれて期間が長くできる」というような事がチラとでも頭によぎるようなKPIなら無い方が良いのでは無いですかね。

少しまとめ

いくつか例を挙げたりしてみましたが、結構難しい気がしませんか?

「数字を追えば良い」というのは物事をシンプルにしてくれるので、迷いなく集中できるための一つの方法であるとは思います。ですが適切な項目を見つけていくのが非常に難しいと私はよく考えます。

受託獲得の営業メンバーがいるような組織だと「どんどん営業が取ってくるけれど現場の手は足らず、常に炎上状態で結果的に仕事が終わっていかない」というような事があったりするのではないでしょうか。獲得するところをKPIにしてしまうとそういう事が起こるのでしょう。

気にしている数値

これまで社内に特に伝えてはいませんでしたが「気にしている数値」は存在すると話しました。それは

「『受講生が目標としていた技能を身につけた』と少なくとも我々と本人が合意できるような状態がどれくらい作れたか」

です。これでも主観や曖昧さが残るものではありますが、例として挙げた他の数値よりは暗黒面に落ちにくく、「できるできない」で測れる比較的曖昧になりにくい数字だと思っています。

本来は売上や利益のゴールを達成する為の数値をKPIとすべきかと思うのですが、今の所はそういう事にはなっていません。ただし「長期的にはこの考え方で発展は得られる」と考えています。

おしまいに

そんな感じで、よく世間で導入されているからと言って安易に決めると危険では?という話でした。

数字を簡単に掛け算すれば結果が出るようなものであればこんなに楽な事は無いですが、そうでないからこそ面白みもある気がします。法則に従えば良いようなものであればすぐ飽きてしまいますからね。

*1:代わりに私が疲労困憊でした(笑)