VOYAGE GROUPの企業ブースと登壇資料まとめ #phpcon2017

目次

こんにちは!
ECナビエンジニアのゆきみねです。

日が空いてしまいましたが、10/8(日)に PHPカンファレンス2017 がありました。

今年は弊社エンジニアが 2名登壇 し、企業ブースでは 実コードを交えた改善事例やエンジニア評価の基準や結果レポートの公開 を行いました。

本記事では、PHPカンファレンス2017の 弊社企業ブースの様子登壇資料 をご紹介します。

企業ブースの様子

f:id:yuk4420:20171016171758p:plain

企業ブースでは、事前に告知 した通り、以下のテーマでVOYAGE GROUPの事例を紹介しました。

  • テーマ1. 事業拡大に全振りしてきたwebサービスの実情とこれから
  • テーマ2. チーム全員リファクタリングしかしない日
  • テーマ3. エンジニアによるエンジニアの評価

ブースにお越しいただいた方からは

「評価基準や評価フィードバック、企業ブースで公開しちゃうんですね」

「評価の結果レポートが全社員に公開されるのスゴイですね」

という声から

「テストコードを書いて改善していくと工数が以前より掛かると思いますが
ビジネスサイドにどう説明しましたか?」

「リファクタリングの日はなぜ月1なんですか?
他の日はリファクタリングしないんですか?」

「マネジメント中心のエンジニアの技術力はどうやって評価していますか?」

「評価者の評価スキルを上げる工夫はしてますか?」

といったリアルな質問まで、幅広いコメントをいただきました。

自分も聞いてみたいという方、是非ajitingしましょう!
※ 詳細は記事下部

また、上記テーマの他にも以下の資料をネタに ajitofm の宣伝も行いました。
お越しいただいた方の中にはリスナーの方も!ありがとうございます!
(左半分:来場者に配布したチラシ、右半分:注目を集めていた!?ポスター)

f:id:yuk4420:20171016193405p:plain

登壇資料

発表1. 広告配信管理システムを支えるPHP〜レガシーシステムからの段階的移行戦略〜

登壇者名:鈴木 健太( @suzu_v

speakerdeck.com

www.youtube.com

発表2. 運用、追加開発しづらいPHPアプリケーションに未来を与える方法

登壇者名:田中 改( @ara_ta3

speakerdeck.com

www.youtube.com

ajitingしましょう

今年のPHPカンファレンスも、企業ブース、セッション共にたくさんの方にお越しいただきました。 この場を借りてお礼申し上げます。

カンファレンス当日ブースに行けなかったので話が聞きたい、登壇者と話がしたいという方、是非 ajiting*1 しましょう!
@tech_voyage までお気軽にメンションください。

*1:VOYAGE GROUPでは社内Bar AJITOで飲んで語らうことをajitingと呼んでいます。

#phpcon2017 で2名登壇します!企業ブースでは実コードや評価の仕組みを公開します!

目次


こんにちは!
ECナビエンジニアのゆきみねです。

10/8(日)は何の日かご存知でしょうか?
そうです!PHPカンファレンス2017 ですね!

PHPカンファレンスは今回で22回目となる、国内最大級のPHPイベントです。
VOYAGE GROUPは昨年に引き続きプラチナスポンサーとして協賛しています。

昨年はブースにて実コードを交えた事例紹介を行い、多くの方で賑わいご好評をいただきました。 techlog.voyagegroup.com techlog.voyagegroup.com

今年は弊社エンジニアが 2名登壇 し、企業ブースでは 実コードを交えた改善事例やエンジニア評価の基準や結果レポートの公開 を行います!
昨年好評だった ECナビ 以外のサービスにもスコープを広げ、fluct SSPサポーターズ の改善事例もご紹介します。

セッション発表では老舗Webサービスのレガシーコード改善事例をご紹介

VOYAGE GROUPは以下2セッションで発表を行います。
「広告配信管理システムを支えるPHP」では fluct SSP の、「運用、追加開発しづらいPHPアプリケーションに未来を与える方法」では サポーターズ の改善事例をご紹介します。

発表1. 広告配信管理システムを支えるPHP〜レガシーシステムからの段階的移行戦略〜

発表者:鈴木健太(@suzu_v)

時間・場所:13:35〜14:00 4Fコンベンションホール梅(手前側)

発表資料から抜粋:

f:id:yuk4420:20171005142613p:plain

f:id:yuk4420:20171005142638p:plain

発表2. 運用、追加開発しづらいPHPアプリケーションに未来を与える方法

発表者:田中 改

時間・場所:15:20〜15:45 4Fコンベンションホール梅(手前側)

発表資料から抜粋:

f:id:yuk4420:20171005180811j:plain

f:id:yuk4420:20171005180942j:plain

f:id:yuk4420:20171005180946j:plain

※ 発表資料は変更する場合があります

両タイトルとも、分かる!なるほど!が盛りだくさんのセッションとなっております!

企業ブースでは実コードを交えた改善事例やエンジニア評価の基準や結果レポートを公開します!

具体的には以下のテーマを予定しています。

またセッション発表後は登壇者もブースにいますので、発表に関する質問・相談の場としてもご利用ください。

テーマ1. 事業拡大に全振りしてきたwebサービスの実情とこれから

サポーターズ の改善活動を実コードを交えてご紹介します。

テーマ2. チーム全員リファクタリングしかしない日

ECナビ の改善活動を実コードを交えてご紹介します。

techlog.voyagegroup.com

テーマ3. エンジニアによるエンジニアの評価

VOYAGE GROUPのエンジニア評価制度について、評価基準実際の結果レポート() を用いてご紹介します。
エンジニアによる評価によって、改善活動も評価される仕組みをご紹介できればと思います。

techlog.voyagegroup.com

※ 企業ブースの内容は変更する場合があります

当日会場でお会いしましょう!

VOYAGE GROUPからは CTO 小賀、発表者 鈴木、発表者 田中、若手4名(僕を含む)の計7名で参加します。

参加登録(無料)がお済みでない方、大丈夫です、まだ間に合います。
応募フォーム

当日が楽しみです!

React + RxJSで始める状態管理

こんにちは、fluctの@nekoyaです。

今日は現在開発に携わっている、俗に言う「管理画面」のWebアプリケーションのアーキテクチャをご紹介します。

このアプリケーションはReactRxJSを軸として作られており、コードはTypeScriptを使って書いています。

アプリケーションを流れるデータと状態の管理について、Write StackとRead Stackという考え方を取り入れたところ、いろいろなメリットが得られたので、そのあたりを軸に掘り下げてみます。

全体の大まかな構成

各Stackの前に、まずはアプリケーション全体の構成をざっくりと見ておきます。

Application Stack

流れとしては、DispatcherからWrite Stack, Read Stackを通ってStateが生成され、それをViewが受け取るという構成になっています。

全体の流れとしてはFluxっぽい何かのひとつのあり方なのですが、Stateを生成する部分をWrite StackとRead Stackに分けて考えているところに特徴があります。

また、サンプルとしてURLで指定したidのissueを表示するアプリケーションを用意しました。簡易的なものですが雰囲気はつかめるかと。

cloneして

make

とだけ実行すれば、ビルドからテスト用のnginxコンテナの起動まで一気にやるようにしています。http://localhost:18888/からアクセスできます。

nginxコンテナがそのままコンソールに居続けるので、終了する時はCTRL+Cで止めてください。

Node.jsとyarnが動く環境が必要ですが、そのあたりは各自適当にやってください。

CQRSに基いてデータフローを組み立てる

このWrite Stack, Read Stackという考え方はAlmin.jsからの引用で、その背景にはCQRSの概念があります。

CQRSについては「複雑を増すだけだ」という考えもあるかもしれませんが、少なくとも我々が業務で取り扱っている領域において「データの更新」という副作用を局所化できるメリットは大きいと捉えています。

Alminそのものを採用しなかった理由としては、

  • 当時のAlminがTypeScriptをサポートしていなかった
  • RxJSを組み合わせるには独自に実装した方が都合がよかった

といったところがメインですが、Alminの根本思想として「考えながら作る」ということが掲げられており、アーキテクチャへの理解を深めるためには自身の実装を持つのは悪いことではないと考えた部分もあります。

それぞれのStackについて掘り下げる前に、全体をもう少し把握するために各要素について簡単に解説します。

Dispatcher

Viewの操作などに起因する状態の更新を受け取り、一連のデータフローの起点となるオブジェクトです。

ひとつひとつのドメインイベントをRxJSのSubjectとして切り出すようなイメージです。

それを呼び出す部分は実際にはもう一枚wrapper層を設けたりするのですが、今回のサンプルでは省略しています。

Epic

Dispatcherのイベントを受けて、最終的にRepositoryを更新するための処理を定義するレイヤです。

特徴的な部分としては、EpicはRxJSのデータフローを定義するとこまでを仕事としている点でしょうか。

データが流れてくる度にEpicが仕事をするのではなく、あくまでDispatcherとRepositoryをつなぐだけの役割を持たせています。

Repository

何らかの値を格納する場で、Write StackとRead Stackの橋渡しをする存在となります。Write Stackの終点であり、Read Stackの始点であるとも言えます。

Repositoryは自身が初期値を持つようにBehaviorSubjectを使っています。こうすることでWrite Stackが未実装の段階でもViewの開発を進めることが可能となり、チームでの並行作業なども進めやすくなります。

Store

DispatcherおよびRepositoryを入力として、単一のState Objectを生成するのがStoreです。

Epicと同様、StoreそのものはRxJSのデータフローを定義することを責務とします。

実装としては各種入力をcombineLatestでひとまとめにするだけです。

State

Viewを生成するためのアプリケーションの状態を集約した単一のオブジェクトです。

実装としては単にinterfaceをひとつ置いているだけです。

View

Stateから一連のDOM Treeを生成するReact Component群です。

ここで扱うReact Componentは全てReact0.14から導入されたStateless Functional Component(とは最近は言わなくて単にFunctionalなComponentというっぽい)としています。

そうすることで、React Componentから状態を排除してDOM Treeの生成のみを任せることができ、Viewのレイヤに複雑さを持ち込まないようにしています。

先の図ではViewがDispatcherを直接操作するように見えますが、実際にはここはもう一段抽象化しています(本エントリはWrite StackとRead Stackの解説がメインのため省略)。

全てのComponentが状態を持たないという前提を敷くことで、Componentの分割はその状態を考えることなく、表示の都合だけで切り分けられるため自由度が高くなります。

また、状態をReact Componentに持たせるとRxJSを使ったデータフローとの接合部分が煩雑になりがちなため、切り離すことでView領域の責務を軽くできるというメリットも得られます。

Write StackとRead Stack

さて、本題に戻ってWrite StackとRead Stackの分割について改めて考えてみましょう。

Write Stack

Write Stack

Dispatcherを入力として、Repositoryに何らかの値を保存するところまでをWrite Stackと呼びます。

CQRSで言うところのCommandの系にあたり、アプリケーションの状態を更新するための副作用をこの部分に局所化することで状態を管理しやすくする狙いがあります。

具体的には何らかのWebAPIを通じてデータを取得したり、更新したりといった操作を非同期におこなうなど、外界とのやり取りをWrite Stackに持たせます。

Read Stack

Read Stack

DispatcherおよびRepositoryを入力として、ViewのためのStateを生成する一連の流れをRead Stackと位置付けます。Read StackはCQRSで言うQueryにあたり、Repositoryに変更を加えることはありません。

外界とのやり取りはWrite Stackの段階で全て済んでいるため、Read Stackの実装は全て自身のアプリケーション内で完結できます。

フロントエンドの開発においては、サーバサイドとの連携部分がシステム内に分散していると何かの問題が起きた際の調査が煩雑になったり、機能追加・更新で地雷を踏む場面が増えます。

このアーキテクチャではWrite Stack以外での外界との接触を禁止することで、複雑さを局所化しています。

データフローを単純化するという意味ではDispatcherからStoreへの流れは許可せずに、全てRepositoryを通した方が簡単にはなります。

とは言え、何の操作も伴わないただの値の受け渡し(URLに含まれるパラメータをそのまま描画する場合など)に

  1. その値を格納するRepositoryを用意する
  2. Dispatcherの値をそのままRepositoryに流す経路をEpicに作る

という実装を毎回用意するのは無駄が多いため、DispatcherからStoreへの直結ルートを用意しています。

このアプリケーション構成ではViewに何らかの変更を起こすためには、必ずDispatcherに値を流してデータのフローを回す必要があります。

この直結ルートがあることで「面倒だからViewの中だけで完結させよう」という邪念を封じる効果が得られます。

何がうれしいのか

文中にも書いていますが、改めてこの構成によって得られたメリットをまとめます。

Viewから複雑さを排除できる

React Componentに状態を持たせず、Viewの再描画には常にStateの再生成を要求することでViewの責務を軽くしています。

こうすることでRead Stackをアプリケーション的に参照透明なものとして扱うことができ、Viewの見通しが良くなります。

また、将来的にもしReact以外の何かを使いたくなった場合もViewの責務が軽いので乗り換えやすくなることが期待できます。

副作用あるいは外部への依存を局所化できる

近年のフロントエンド開発においては、外部のリソース(WebAPIなど)との非同期通信とその結果を受けての処理がアプリケーションが複雑化する主な要因であると考えています。

この構成では、その複雑さを受け入れる場所をWrite Stackとして明確に定めることで「あちこちでコールバックが発生して収集がつかない」といった状況を避けることを目指しています。

これが効果を発揮したかが本当の意味で分かるのは数年先のことかもしれませんが、思考の整理のしやすさという恩恵はプロジェクトの初期段階から得られている実感はあります。

懸念される課題

あらゆる状態変化に対してViewが再構築される

React Componentに状態を持たせないということは、何らかの状態の変更に対して常にデータフローを一巡させ、Stateを再生成し、Viewを再構築することを意味します。

高いパフォーマンスが求められるケースでは不利になる場合もありますが、我々の業務ドメインにおいては構成がシンプルになるメリットの方が大きいため、ここには目をつぶっています。

少なくとも現時点ではReactのVirtualDOMに全て任せてしまって問題のないレベルのパフォーマンスが得られています。

初期学習コストが高くなる

例えば公開期間が限定されているようなキャンペーンサイトであれば、このようなStackを分けた構成は必要ないかもしれません。

我々が現在取り組んでいる「管理画面」というものは何年にも渡って使われる(もちろん会社やビジネスが存続するという前提はありますが)ことを念頭に置く必要があるため、初期学習コストを下げることはそこまで重要視していません。

コード量が増える

アプリケーションを構成する要素が増えるため、実際のところコード量は増加する傾向にあります。

この課題については、TypeScriptを採用していることでIDEのサポートも得やすくなっているため、コードの絶対量に対して人間がやるべきことを抑えられているため許容可能であると感じています。

まとめ

フロントエンドの状態管理には様々なアプローチがあり、問題領域によっても適切な手法は違ってくるでしょう。

「状態をどのように扱うか」という問いはアプリケーションの本質的な課題であり、そのあり方については常に向き合い続けるべきであると考えます。

そんなひとつのあり方として、今回ご紹介した手法が何かのきっかけになれば幸いです。

sltd, AWS Athenaを使ってLDAPサーバの監査体制を強化した話

こんにちは、VOYAGE GROUP システム本部の @s-tajima です。
今回はVOYAGE GROUPが提供する多くのサービスをより安全に運用するために、LDAPサーバの監査体制を強化したお話です。

VOYAGE GROUPでは、 サーバにログインするためのシェルアカウントや、各種管理画面のアカウント等、様々なアカウントの統合管理のためのシステムとしてLDAPサーバ(OpenLDAPのslapd)を利用しています。つまり、このLDAPサーバに対して誤った操作や悪意のある操作が行われることで、それぞれのシステムに意図しない認証や認可が行われてしまうことになります。

そんな状況を予防, 検知するために、

  • LDAPサーバに対する参照・更新の記録をすべてログに残す。(自動)
  • ログの中身を確認し、必要なものがあれば通知する。(自動)
  • 通知の内容を元に詳しい調査を行い、問題がないか確認する。(人力)

という環境を用意しました。 こんな環境を実現するために、どんなシステムを構築したかというのを紹介します。

f:id:s_tajima:20170824214527p:plain

Step1: LDAPサーバ(slapd)による監査ログの出力

slapdで扱えるログは大まかに分けて3種類あります。
それぞれのログの良い点/悪い点は以下の通りです。

  1. Log (通常rsyslog経由で出力される)
    • [+] 1行毎に意味を持つログファイルベースで出力可能
    • [-] LDAPのデータベースに対する参照・更新の内容が完全に出力されるわけではない
  2. AccessLog (Overlay)
    • [+] LDAPのデータベースに対する参照・更新の内容が完全に出力される
    • [-] この情報自体がLDAPのデータベースに記録されるので取り扱いが面倒
  3. AuditLog (Overlay)
    • [+] 指定したファイルに出力可能
    • [-] ただしフォーマットがldifなので複数行をまとめて扱ってはじめて意味のある情報になる
    • [-] 出力されるのは更新の情報のみで、参照については出力されない

今回の要件だと、参照・更新の情報を完全に出力しておきたかっため、AccessLog を使うのが妥当そうだと判断しました。

Step2: sltdによる監査ログのS3への転送

VOYAGE GROUPで管理しているLDAPサーバは1台だけではないので、ログを出力したそのサーバ上で中身のチェックをするのではなく、どこか別の場所に転送し一箇所にまとめておくとその後の調査がしやすいです。しかし、ここで課題になるのがログの収集方法です。前述の通り、slapdのAccessLogはそれ自体がLDAPのデータベースに書き込まれていきます。

最初に思いついたのは、AccessLog用のLDAPデータベースをレプリケーション等で集約するためのLDAPサーバを用意することですが、実際にはすべてのLDAPサーバと直接通信することのできるサーバを用意するのが難しかったために断念しました。

そこで今回は、後述するAmazon Athenaによるクエリを利用することを目論んですべてのLDAPサーバのログをAmazon S3に転送することにしました。

これを実現するための方法はいくつか考えられますが今回は、

  • AccessLog用のLDAPデータベースを LDIF backend にする。
  • 出力されたLDIFファイルを読み込みJSONに変換(Athenaによるクエリのため)し、S3に転送する機能を持ったソフトウェアを作成する。

という方法をとりました。 このソフトウェアは、sltdという名前でVOYAGE GROUPのGitHubリポジトリにて公開しているので興味があればご覧ください。

Step3: AWS Athenaによる操作内容の通知

sltdによってS3に転送したログをAthenaにて集計し、特定の条件に合致するものがあればSlackに通知する仕組みを作りました。セキュリティの都合上、通知の条件については割愛しますが、以下のように通知されます。

f:id:s_tajima:20170824214444p:plain

最後に

最近では、Zero Trust Networks にかかれているような、LDAPサーバのような中央集権型のアカウント管理システムを使わずにすむように、オンデマンドでテンポラリなアカウントを発行するシステムの設計が便利そうではありますが、長い歴史を持つサービスを数多く運用しているとなかなかそのような環境に切り替えていくのは難しかったりします。

今回の監査体制の強化によって、今までよりも安心してLDAPサーバを運用できるようになりました。また、今まで限られたメンバーでのみ行っていたLDAPのデータの更新を、もう少し広い範囲に広げていくこともやりやすくなりました。

監査体制の構築はサービスを運用する上でとても大切な話だと思いますが、セキュリティ上の問題などもあるためか実運用に関する話をインターネットで見かけることがあまりないような気がしています。このような話に興味がある方は、是非 #ajiting でお話しましょう!

SIer時代に学んで今でも役に立っていること、Web系の会社に入ってから考えを改めたこと

こんにちは、株式会社fluctで fluctSSPの広告配信に関わっている坂本です。

私はfluctでは新しい広告(PMP, NativeAd)の追加をしたこともありましたが、ここ1年半くらいは自分で追加した広告機能や既存機能のサポートエンジニアとして働いています。
(インフラの保守・運用は専門部署があるのでおまかせしています)

経歴

  • SIer(金融・ECサイト開発等)のピラミッド構造で開発に従事していた6年
  • Web系の会社(VOYAGE GROUPとは別会社)にてSESとして仕事をしていた4年(ここ終わりでVOYAGE GROUPに転職)
  • Web系の会社(VOYAGE GROUP/fluct)にて正社員として2年半~現在に至る

今の自分の行動指針はSIer時代に培われたものがほとんどですが、Web系の会社に入って考えを改めたものもあるので、自分のスキルの棚卸しを兼ねてそれを整理してみます。(サポートエンジニアに限った話ではなく、いちエンジニアとして心がけているものです)

現SIerの方が転職する際のお役に立つかもしれませんので、自分が転職した時のことも少し書いてみます。

おそらく殆どの人にとっては当たり前すぎることしか書いてないと思います。
技術的な話を期待されている方、ゴメンナサイ。

目次

Web系会社に入ってからSIer時代の経験が役に立っていると思うこと

1. 自分が関わっているサービスを使っている人と綿密なコミュニケーションをとること

 幾つか理由があるので箇条書きにします。

  • 理由1. 使う人(社内・社外問わず)がどう使っているのか?を把握するため。
    ヒアリングをして分かる話だけではなく、問い合わせや小さな障害対応などを通じて業務理解・ユースケースをどれだけ深めるか。という二つの軸で情報を集めることが大事だと考え行動しています。どちらかだけでは機能改修の時に、微妙な結果(※)になったことが過去にあったためです。
    • 微妙な事例1 : 社内向け画面の改修時にユーザ部門の意見を取りまとめてしまったがゆえにニュアンスがぼやけてしまいユーザ部門の実業務と乖離してしまった
    • 微妙な事例2 : 保守対応時にユーザの意見をそのまま聞いてしまい、ツギハギだらけの機能になってメンテナンスしづらくなった
    また、こまめにコミュニケーションをとっていると分からない言葉が出てきた時に都度確認できるので、DDD界隈でよく話題に上がる「ユビキタス言語の整理(辞書化)」を自然に進めていくことになると考えています。
    Backlogなどを使いノウハウや問い合わせ内容を貯めていければ同じ問い合わせは減らすことも出来ます。
  • 理由2. 相談しやすい関係性を構築するため
    誰もが思っていると思いますがエンジニアと非エンジニアの間には壁ができやすいものです。自分が過去に関わって壁を放置したプロジェクトはうまくいっているものは無かったです。
    「管理画面の余り使わない画面の使い方がわからない」みたいな比較的影響度が小さいことがわかっている問い合わせだったとしても、積極的に関わりに行くことで「この人には相談してもいいんだ。」という気持ちになってもらい、アラート検知システムに引っかからない何かがあった時に迅速に情報をあげてもらえるような関係性を保つことが重要。(検知システムが無くていいとかザルでいいという意味ではありません。)
    では、その時にどう振る舞えばいいのか?というのは以下にまとまっています。特に5. 常に機嫌よくいる。(≒聞きやすい雰囲気を作る)が一番大事だと思っています。が、忙しいとすぐに崩れてしまうので注意が必要(自戒を込めて...)。

    techlog.voyagegroup.com

  • 理由3.普段の小さなお問い合わせに対応することで、障害対応のスキル/ドメイン知識を少しずつ身につける
    • 影響範囲の特定
    • 調査力
    • 一次対応(ビジネス上システムが適切にに動くためのパッチ)の立案
    • 根本対応の立案と補償等の影響
    • サービスとしての危険度の判断力(ドメイン知識)

2. 全体像を図示して関係者間の認識齟齬を少なくすること

SIer時代、新しい部署や会社に入った時に担当するシステムの概要図すらなくて概要を把握するのが大変だったという経験があったことから、自分で色々書くようにしています。
私は文章ではなく図示することの方が好きです。理由は図のほうが情報量が多く誤解を招かないためです。
自分で書いてみて、以下の価値があるのではないかと考えています。
(存在する事自体の価値と、自分が書く過程において生まれる価値の二種類)

  • 機能追加のときに関係者全員で同意をとるのに理解してもらいやすくなります
  • 他のエンジニアにコードレビューしてもらう時に概要把握してもらいやすくなります
  • プロジェクトに参入してきた誰かに説明するときに使うことで人に説明するコストが下がります。(自分が思い出すコストも下がります)
  • 書くことで、俯瞰的な視点でサービスを捉えやすくなり、障害対応時の影響範囲の確定や、計画・見積もりが正確になると考えています

注意点

細かく書きすぎないこと。
細かすぎるとコードとドキュメントの乖離問題につながるので、私は以下で十分だと思っています。(これらでもメンテナンスしないとすぐに乖離していくので常に更新するようにしています)

  • 業務フロー図(プロセス図)
  • ユースケース図
  • ER図 <= エンジニア向け

fluctでは新卒・中途に関わらず新しくエンジニアが入ってきた時、「エンジニアクルーラリー」という
`機能毎の説明を一番詳しい人がリレー形式で行い、システム全体の理解を深めてもらう` という取り組み( 全体概要 -> 管理画面 -> 配信 -> バッチ -> インフラ ... と説明)をしていて、自分が説明する際にこの取組で書いた図を使うようにしています。 

3. 自分が作ったものを見届ける(サービスクローズに立ち会う)こと。

SIer時代に追加開発するチームと保守するチームが違っていることが多く、追加開発するチームの品質が一向に上がらないことがありました。
保守チームにいた自分がその当時の先輩に「どうして追加開発チームの品質が良くならないのか?」と質問したときの答えが「自分で作ったものを見届けないエンジニアは成長しづらい。」と言うものでした。
新規開発だけしている人は運用時のPDCAに参加するのが難しいので、自分の作るものの品質を改善する機会を失っていることになります。
私は保守運用側の立場なので、開発だけをやって離れてしまったエンジニアにこんな改修があったよ。ということをなるべく伝えるようにしています。そのエンジニアが次の開発を行う時に頭の片隅においてもらえるように。
Web系の会社では比較的スクラップ・アンド・ビルドが多いのでその機会には恵まれているのではないかと思います。
使われなくなった機能のコードを消すことが `尊い` と言われますが、その機能が何故使われなくなったのか?まできちんとふりかえるとより効果があるのでは?と私は思っています。
fluctに入ってからは中々見届けることが出来ていないのですが、若い子たちにそういう動きを取ってもらいたいと思っているので、促すようにしています。

Web系の会社に入ってから考えを改めたこと

1. バージョンアップへの追随を怠らないこと

コアシステムのバージョンアップでも社内向け管理画面でも、テスト/監視系/リリースフローが充実していれば同じように積極的に動くべきだと思います(メジャーバージョンアップについては検討の必要あり)。
SIer時代は最初に作った時のバージョンで塩漬けにする事が多く、塩漬けにしたことで後々辛くなることが多かったのでこの点は考え方を改めました。

具体的には以下参考。

techlog.voyagegroup.com

 

2. 小さく・早くはじめるために、さくっと作る

「どうすれば、新しい広告(サービス)をユーザに提供できるのか?」をビジネスサイドの人間と一緒に考え、「最初は手数を減らしてでもとりあえず動くものを作れるか?」を考えること。
SIer時代はどうしても「納品」という概念があったので(チームが別なことが多い)納品後のことまでセットで自分で調整するのは難しかったのであまり意識していなかったのですが、
全て自分でやらないといけないWeb系ではリリース時に必要最低限なものだけを作って後は機能追加でカバーするということを最初はうまく切り分ける事ができていませんでした。
今は少しずつ出来るようになってきているかなと思っています。

おまけ1 : SIerからWeb系に転職しようと思った時にどう動いたか?

転職エージェントさんに相談した上で、自分の強みが何か?を考えてアピールするようにしてみました。
(転職しようと思ったのは2014年6月、実際に転職したのは2015年2月のことです)

  • VOYAGE GROUPではない広告配信している会社に合計で4年程SESとして仕事をしていたので広告配信の業務知識があった(SESの前に少しやっていたのも併せると5年弱の経験があった) => そこを押してみようと考えた。
  • SIer時代に10Projectほど追加開発・保守をバランス良く経験して、このプロジェクトが何故、成功・失敗したのか?を色々見る事ができた。
    そこから汎化できるようになっていた(当時の上司から、「失敗したときだけではなく、うまく行ったときにもきちんとふりかえりを行い、うまく行った理由も考えるといい」と言われ、それを自分の中に積み重ねることが出来ていたので自分の中で汎化できていたのではないかと思っています)
  • 私は「XX(言語、インフラ等)がやりたい <<<< 使ってくれる人の声を聞いて仕事がしたい(裁量権をもって仕事がしたい)」と普段から考えています。
    保守・運用っぽいことをやりたがるエンジニアは少ないのでそこもアピールしてみました。

おまけ2 : SIerから今の会社に転職して良かったこと、微妙だと思っていること

  • 良かったこと
    • 自分と同じような考え方を持っている人と一緒に仕事ができること
    • エンジニアにかかわらず若くて優秀な社員が多い
      が、運用経験値は多いとはいえないので彼らをサポートするという自分の立ち位置を見つけることが出来た。(若い子たちからすると口うるさいおっさんだと思ってるだろうけど...)
    • 正しい(≒やりたい)と思ったことを実行に移すのが比較的容易
      VOYAGE GROUPはかなりハードルが低い方だと思う。特にfluctはVOYAGE GROUPの中でも低く、Rustが本番サービスで動いていたりします。
    • 勉強会に行った時に、取引のある同業種のエンジニアさんたちと交流が取りやすい(SES時代にはビジネス的な話をするのは難しかった)。
    • VOYAGE GROUPに猛者がいっぱいいるので、お話する(あるいは誰かと誰かが話しているのを聞く)たびにいろんな刺激を受ける事ができる。
      (猛者 : 機械学習に強い人、言語の最新動向に精通してる人、@t_wada (※)等々) ※ @t_wadaはVOYAGE GROUP内のfluctを含む幾つかの子会社に週に一度ずつ来ていただいています
    • 事務方が素晴らしい。(改善要望を出すと早いと当日中に改善されたりする)
  • 微妙だと思っていること
    • 状況の変化(ビジネスの話)が激しく、キャッチアップしきれないことがある
    • 少ない人数でいかに回すか?という(うまくタスクを委譲する)スキルが自分に欠けていたためプロジェクトメンバーに迷惑をかけてしまったことがある
    • 個人的に好きな(手に馴染む)Scalaを使う機会をまだ作れてない
      (Scalaで書くより違う方法で解決したほうが早く、サービスレベル向上のためにはそちらを選択する事になっているため)

SIer出身でも自分の立ち位置(武器)を見つけ、当たり前にやるべきことをきちんと遂行できれば何とかなるかなというのが私の転職に関する感想です。

もし(特に猛者たちに)興味が沸いたら、fluctに限らずVOYAGE GROUPは中途採用募集中ですのでお気軽にご応募ください。社内バーAJITOでのカジュアル面談もご用意しています!

voyagegroup.com

 

人工知能学会誌の特集「広告とAI」にZucks Ad Networkの取り組みを寄稿しました

hagino3000です。今週はカナダで開催中のKDD2017に参加しています。

人工知能学会誌の7月号の特集「広告とAI」に「アドネットワークにおける広告配信計画の最適化」という記事を寄稿しました。軽く内容を紹介します。

【会誌発行】人工知能学会誌 Vol. 32 No. 4 (2017/07) – 人工知能学会 (The Japanese Society for Artificial Intelligence)

内容について

導入はインターネット広告事業のタイプ(SSP, DSP, アドネットワーク, etc.)とそれぞれの役割を紹介。中でもアドネットワークは媒体社と広告主の両者の要望を満す必要があるため、広告効果と媒体社収益の2つが要件になる事を説明しました。
インターネット広告を例に出す論文は「クリック課金型広告においてはクリック率の高い広告を出せば良い」という設定をしばしば持ちだします。そのせいかアカデミアの人と話をしていると「ネット広告って、バンディットでクリック率の高いバナーを出していくだけでしょ?」と言われる事があります、が実際はそんな事無いです。

配信する広告を選択する方策については「活用と探索のジレンマ」に軽く触れた後に、広告配信の設定に適用しやすいバンディットアルゴリズムの手法であるThompson Samplingを紹介。報酬を クリック単価×クリック率 とした時の手続きを例に挙げました。

最後にCPA1を制約として媒体社収益を最大化する方策についてまとめています。 記事中では簡単のためにCPAを制約としましたが、広告主が求める効果はCPAに限らず流入ユーザーの継続率やROAS2であったりもします。後者の方がサンプルサイズが小さいため、制約の難易度はより高くなります。

まとめ

今回は地味な内容となりましたが、プロダクション未投入の新奇性のある内容も出せていければと思っています。 「広告とAI」特集の他の記事だと、理研AIP 前原氏による「ディスプレイ広告に対するリアルタイム入札」はRTBの入札戦略を離散最適化で解いているのが面白かったです。RTBの入札戦略を俯瞰している日本語の文章は他に見た事がないので、その点でも貴重だと感じました。

AI書庫へのリンク


  1. コンバージョン獲得1件あたりのコスト

  2. 広告経由で流入したユーザーによる売上を広告費用で割った物

builderscon tokyo 2017 で #ajitofm の公開収録をしました!

こんにちはこんにちは!株式会社 fluct で Web 広告配信のお手伝いをしている @jewel_x12 です!

皆さんは builderscon tokyo 2017 へ参加されましたでしょうか!?様々なセッションがあり、The・ギークのお祭りでしたね!楽しかった!

VOYAGE GROUP はランチセッションスポンサーとして、1日目のランチセッションに ajitofm 公開収録をさせていただきました。

ajitofm って?

ajito.fm

ajitofm とは VOYAGE GROUP の社内バー AJITO での語らいを収録したポッドキャストです(実は AJITO で収録していないという爆弾発言が公開収録でありました)。 すずけんさん(@suzu_v) を中心として、精力的に更新されているので興味がある方は聞いてみてください!VOYAGE GROUP のエンジニア事情や面白い話が色々聞けます。

ランチセッションで公開収録をすることになった経緯

せっかくランチセッションの枠をいただいたので、VOYAGE GROUP をより知っていただくために何かコンテンツがないかと考えていました。下記のようにぼやいていたところ

f:id:jewel12:20170807192400p:plain

すずけんさんがやりますよーと言ってくださったのでその方向でよしなにやることになりました。YAPC (Yet Another Perl Conference)発なのかどうかは要出典。

最初はトークセッションをするだけのつもりだったのですが、社内PAさん(@brtriver)の存在もあり収録にもチャレンジしてみることに。 会場にマイク 4 本とミキサー、ケーブル類を持ち込み、前セッションとの入れ替わり時にセッティングという流れでした。こういう入れ替わり時にセッティングするというような、余裕のないデプロイは大体失敗すると思っているのですが、PAさんの腕が確かなのかうまくいってよかったです!どきどきでした。

音響周りをカスタマイズしたり、机や椅子を用意していただくなどいろいろなワガママに付き合っていただいたスタッフの皆様には本当に感謝しております。

当日の様子

#builderscon ランチセッション始まりました! #ajitofm

builderscon.ioさん(@builderscon.io)がシェアした投稿 -

収録に参加したすずけんさん・ajiyoshi さん・トミールさん・yowcow さん

f:id:jewel12:20170808114541j:plain

無理やりトークパネルを埋めました。

f:id:jewel12:20170808114327j:plain

PAさん(@brtriver)の様子。手つきが素早いですね。私は主にスポンサー業としてスタッフさんとやり取りをしたりチラシを作ったりだったので当日はたいしてやることが無く、イベントホールをブラブラしてました。朝食が美味しかったですね!

30 分あっという間でしたが Twitter などで様々な反応をいただいたので、やってよかったです!

twitter.com

スタッフさんや会場の柔軟さ、腕のいいPAがいるなど、いくつかの条件が重ならないと実現は難しいかもしれないですが、テック系ラジオをされている方はこのような登壇方法もいかかでしょうか!?

最後に、スタッフの皆様、登壇された皆様、とても楽しいイベントを提供してくださりありがとうございました!

今回収録した内容は ↓ から聞けます!公開収録で ajitofm に興味を持ってくださった方は他の回も聞いてみてください!

ajito.fm