emahiro/b/logs

勉強記録と書評とたまに長めの呟きを書きます

環境を変えた時に先にしておくといいことをまとめてみた

最初に

※ これは個人的な経験をもとにして記載しました。

Summary

転職したり、異動したりで新しい環境に所属することはエンジニアに取って珍しい話ではありませんが、新しい環境に行った時に先んじて理解しておいた方が良いと思われることをまとめて見ました。

環境編

  1. チュートリアルを読む
  2. トイレの位置を把握する
  3. 勤怠ルールを確認する
  4. New Commer 専用のチャット部屋を作る

エンジニアリング編

  • デプロイルールを覚える
  • デプロイをする

環境編

チュートリアルを読む

ある職場はいい職場だと思います。
異動直後、入社直後のチュートリアルがあると、教えてもらう側も教える側もコスト少なく、必要な情報を伝えることが出来ますし、例えば入っておくべきメーリスや、最低限のslackのチャンネルなどNewCommerが自律的にセットアップできるような仕組みはあるとすごくよいと思いました。

もしない場合は、すぐに作ったほうが良いと思います。

  • エンジニア向け
  • ビジネス向け

など色々種類はあると思いますが、業種分あるのがおそらく理想なのだと思います。

自分もそうですが、NewCommerのころの最初の1ヶ月位は結構緊張して、生産性が上がってこないので、極力、気を使うことを減らしてあげて

トイレの位置を把握する

重要です。できれば個室の個数も数えておくと良いと思います。
入りたてのころはこういう些細なところで体力消耗するので当日に調べておく、できればピークタイムを最初の一週間くらいで覚えておくと良いと思います。

喫煙者の方は喫煙所のある階、及び喫煙ルールとかも調べておくと良いと思います。近頃は禁煙の流れなので、電子タバコしか吸えなかったりとか細かいルールがあると思うので調べておくと良いかもしれません。

勤怠ルールを確認する

重要です。いくら自由な職場だったとしても最低限のルールはあるものだと思うので、そのルールは予め確認しておくといいと思います。
勤怠は同じ会社でもチームによって違ったり、職種によって異なったり、勤怠連絡の仕方とかもメールなのかチャットなのか色々ルールがあると思うので、当たり前ですが入社当日に知っておくべきだと思います。

※ NewCommer向けチュートリアルに書いて有るべきですね。

New Commer 専用のチャット部屋を作る

※ これは実際に運用されているのを見てすごく良い仕組みだと実感しています。こういうことに気づける人材になりたいです。

初日からチャットであれこれ話せる人は(いるかもしれませんが、)まれな人材だと思います。
New Commerである以上、最初の数日は同僚の顔と名前も一致しないし、ましてチャットで話されている内容なんて、まず事業も環境も知らないのにわかるわけがないと思っています。

しかも、雑談チャットとかでもいきなり自分から声をかけるのは難しいと思います。周りは気軽に聞いてねー!みたいなことを言っても、僕もそうですが、初心者がいきなり気軽に話しかけに行けるわけがありません。
結構ストレスです。

なので、予め歓迎用チャンネルとか作って、部署の人、業務で関わる人は先に入っておく。そして、New Commerはそこで色んなことをつぶやきベースで聞いてみて、部署の人はそのつぶやきを拾ってあげる。そういう流れにすると、馴染みやすくなるのではないかなと思います。自己紹介なんかもそこですると良いかなと思いました。

チャットは例え部署のprivateな雑談チャットだとしても、公共の場です。公共の場でいきなり自分の発言をするのは負荷がかかります。そのため、ある程度NewCommerのpersonalな環境を用意してあげて、ゆるふわに色んなことを話せる場を作る、そうするとチャットでの発言がしやすくなって、ひいては仕事の話もしやすくなるのではないかなと思います。

ちなみに、チャンネル名は welcome-XXXX とか tutrial-XXXX とかが良いのではないかなーと思います。対外的にもわかりやすいですし。
※ これは入社時点で予め作ってあるとすごく良いですね。

コミュニケーションは仕事の基本なので、そのコミュニケーションの最初の一歩をどれだけ後押ししてあげられるかがその人が馴染める初速につながっていくと思います。
これによりコミュニケーションが円滑に進み、仕事のスピードに繋がり、ひいては事業スピードに繋がっていくと思うので、この仕組みは本当に良い仕組みだなと思っています。

エンジニア編

エンジニアとしては

  • 開発環境構築
  • システムの理解

など最初にやるべきことはある程度決まっています。

その中で個人的に、ある程度慣れないとやらないことだけど、先にしておくと実はコスパが良いのではないかと思ったのがデプロイ です。

デプロイを先に理解する意図

開発者たるもの、作った機能のコードを書くことだけが仕事ではありません。
リリースして事業に貢献する ことが仕事だと思っています。

そのためリリースをするためのデプロイ権限をエンジニアは持たないといけないと思います。
しかしJOIN当初は当たり前ですが、デプロイ権限はなく、権限を持つ人に依頼することになるのが一般的だと思います。

デプロイ権限を持たないデメリット

リリースが自分以外の誰かに依存してしまうことで幾つか弊害があると感じます。 - リリースするだけなのに、その「誰か」のスケジュールを確認しなければ行けない - 何かバグがあった場合にも切り戻しも依頼しないといけない - つまり、自分以外の誰かに依頼する以上、案件を全て自分でハンドリング出来ない。

デプロイ権限があることのメリット

誰かに依存することがありません。

  • スピード感持ってリリースできる
  • 案件への責任感が生まれる
  • もし仮に問題があっても、実装者である自身が気付けるので、切り戻しが早く行える。

そして何より、自分から進んで案件を拾いにいけると思います。
書いたコードが実際に自分の手で世の中に届けることができる権限を先に渡しておくことで、ずっとスピード感持って開発をしていけるような気がしています。

デプロイを標準化する

デプロイ手順を簡略化、べき等化しておくことは、チームの責任だと思います。
ちょっとしたデプロイでさえ秘伝のタレ化していたり、細かな手順を踏まないと行けなかったりというだけで、開発のモチベーションが削がれます。
誰がしても同じようにデプロイ出来る仕組みを作っておくことは、受け入れチームの責務だと思います。
ある程度揃えておきましょう。

また、権限を取るためのチェック項目や、デプロイ手順もドキュメントにまとめておくと良いと思います。  

デプロイて権限管理等が悉皆されていると後回しになりがちなことだと思います。
ただ、これを早い段階で誰かに依存せずにNewCommer1人で出来るようにしておけば開発がより早く進むと考えています。

デプロイするにあたって

デプロイルールを覚える

Documentや権限付与のための簡単なチェックシートがあるといいですね。
読み終えたら自動的に権限付与、くらい裁量があるとことがスムーズに運ぶと思います。

デプロイする

簡単なチケット等の実装をして、見守られつつも早い段階でデプロイまでしておくと良いかと思います。
最初のデプロイは、冷や汗もんですよね。

僕は異動3ヶ月目くらいでようやくもらってその前後で生産性や仕事へ意識が変わった実感があったので、これは先に経験しておくとよかったなぁと後悔したところだったので記載しました。

まとめ

僕は特にそうですが、新しい環境ってめちゃめちゃ緊張します。
一緒に働く人の顔と名前も定かでない状態でいきなり100%のパフォーマンスは出せません。
NewCommerにできるだけ早く100%の力を出させてあげる、そのための小さな障害やストレスになりそうなものは予め軽減しておくことは会社、受け入れるチームの責任であると思っています。

めんどくさがらずにチュートリアルも歓迎チャンネルも用意しておくときっとNewCommerが馴染むまでの時間を軽減できます。
そしてそれがそのまま事業スピードにつながると思うので、こういうちょっとした気遣いやオーバーヘッドかもしれないことをこなしておくといいです。
最後にトータルで見たときに結果を実感するようなものなので、最初は腰が重いかもですが、ある・なしで本当に異なるなーという実感があります。

個人でもwelcomeチャンネルで即レスしたり、新しく入った方が早く環境に馴染める努力はしていきたい所存です。

【Golang】部分文字列を抽出する

golangの文字列から特定の位置の文字を取り出したい時に [:] を使えます。

package main

import (
    "fmt"
)

func main() {
    s := "abcdefg"
    fmt.Printf("%+v\n", s[:])
    fmt.Printf("%+v\n", s[1:3])
}

/* output
> abcdefg
> bc
*/

cf. https://play.golang.org/p/Gp0PYKtnZfA

但し、マルチバイト文字の場合は落とし穴があるので注意が必要です。UTF-8の文字数では使えません。

package main

import (
    "fmt"
)

func main() {
    s := "あいうえお"
    fmt.Printf("%+v\n", s[:])
    fmt.Printf("%+v\n", s[1:3])
}
/* output
> あいうえお
> ��
*/

cf. https://play.golang.org/p/fToYo08XtaD

UTF-8の文字列で部分文字列を抽出するについては以下のような utf8string をパッケージを使うと良いらしい。

qiita.com

GoLandでriotのtagファイルをシンタックスハイライトする

Overview

GoLand(というかIntelliJ)がデフォルトで対応していないtemplateファイルをカスタム登録する方法

以前tmplファイルの設定方法は書きました

ema-hiro.hatenablog.com

手順

前回と同様です。
Preference ▶ Editor ▶ FileType ▶ HTMLを選択。
riot.jsでは *.tag をRegistered Patternsに追加します。

f:id:ema_hiro:20180215010613p:plain

Use httpmock with fmt

Summary

golangのhttpのmocking packageである httpmockfmt packageを使ってstring型に変換したときにハマった話を書きます。

httpmock packageはこちら

github.com

How to Use

var resJson = `
{
  "id": 1,
  "name": "taro"
}
`

func TestHttpMock(t *testing.T){
  RegisterResponder("GET", "https://sample.com/users/1", httpmock.NewStringResponder(200, resJson))
  // some unit test
}

httpmock を使ってurlとmethodを指定するだけで、mockしたいリクエストのResponseを定義できる。
上記では /users/1 の内容に対して resJson で指定したStringをresponseとして登録します。

ハマったところ

上記の別パターンで幾つかresponseの内容を追加でmockしたいとします。以下のようなパターンです

resJson1 = `{
  "id": 1,
  "studentID": 123,
  "name": "taro",
  "age":20,
  "sex": "male"
}`

func TestHttpMock(t *testing.T){
  RegisterResponder("GET", "https://sample.com/users?name=taro&studentID=123", httpmock.NewStringResponder(200, resJson))
  // some unit test
}

上記のようにクエリパラメータでURLを指定してリクエストのmockを用意するケースを考えます。
例えば以下のように、 studentID が幾つかあって、複数のクエリ条件のもとmockするデータを用意するとき

resJson1 = `{
  "id": 1,
  "studentID": 123,
  "name": "katsuo",
  "age":20,
  "sex": "male"
}`

resJson1 = `{
  "id": 2,
  "studentID": 456,
  "name": "wakame",
  "age":18,
  "sex": "female"
}`

resJson1 = `{
  "id": 3,
  "studentID": 678,
  "name": "tara",
  "age":10,
  "sex": "male"
}`


func TestHttpMock(t *testing.T){
  studentIDs := []int64{123,456,789}
  for _, id := range studentIDs{
  RegisterResponder("GET", fmt.Sprintf("https://sample.com/users?sex=male&studentID=%d", id), httpmock.NewStringResponder(200, resJson))
    // some unit test
  }
}

コードは適当ですが、こんなケースをしている、urlを動的にイテレーションでループさせて一括でユニットテストを書きたいみたいなシチュエーションがあると思います。
しかしこのコードは動きません。原因は 適切に特殊文字エスケープされていない からです。

Mockの部分を若干修正したコードが下記です。

func TestHttpMock(t *testing.T){
  studentIDs := []int64{123,456,789}
  for _, id := range studentIDs{
  RegisterResponder("GET", fmt.Sprintf("https://sample.com/users?sex=male%26studentID=%d", id), httpmock.NewStringResponder(200, resJson))
    // some unit test
  }
}

&特殊文字%26エスケープしました。
実はこれでもまだ動きません。

理由は、エスケープした結果の %26% の部分が、format関数で指定されている % をバッティングしてしまって、正確にクエリパラメータを読み込めてなかったからです。

そのため、エスケープした結果、ちゃんと%として使われる必要がある ということだったのです。goのfmtの標準パッケージの中に書いてます。(https://golang.org/pkg/fmt/#hdr-Printing)

fmt - The Go Programming Language

%% a literal percent sign; consumes no value

つまり、%% -> % の文字列として扱えます。なので下記になります。

func TestHttpMock(t *testing.T){
  studentIDs := []int64{123,456,789}
  for _, id := range studentIDs{
  RegisterResponder("GET", fmt.Sprintf("https://sample.com/users?sex=male%%26studentID=%d", id), httpmock.NewStringResponder(200, resJson))
    // some unit test
  }
}

これでMock完了です。

まとめ

httpmockでfmt.Sprintfで文字列型にするときにはエスケープのことを考慮することが必要です。

広告を非表示にする

Cookpad TechConf2018に行ってきた!

こちらに参加してきました

techconf.cookpad.com

基調講演

遅れて参加したので聞いてません。

クックパッドの “体系的” サービス開発

BMLループ

buildの失敗

  • 手戻り?

mesureの失敗

  • ログの取り忘れ

learnの失敗

  • 数字は動いた
  • しかしイマイチ効果がわからない
  • 数字は得られたが学びがない
  • 属人的

Buildの前に行っておくこと

  • BMLループを前から順に行わない
    • 手戻り防止
    • 逐次にやろうとすると結構大きな手戻りが起こる
    • 最初にサイクル全体を設計する
  • 効率的な学び
    • 施策結果に対する予想
      • 現実の理解
      • サービスに対する理解
      • 想定との良し悪し->なんで??
    • どういう結果が出そうなのか?
      • mesureやlearnのフェーズで考える内容を考えておく

Mesureの前にしておくこと

  • 計測結果の選定
  • KPI設定
    • 指標やKPIはそれ単体で存在することは珍しい
    • 通常は別の指標とバッティングする
    • 事前にバッティングする箇所を予想しておく
  • ログの確認、SQLの実行

Learn前にしておくこと

  • 指標解釈の整理
  • 結果の想定
  • 👉成功のイメージを共有する
    • その施策が成功した時に、ユーザーはどういう体験をしているのか?

社内ツール

  • Build
    • 価値仮説シート
    • Chanko
    • EasyAB
  • Mesure
    • 社内ツールがある
  • Learn
    • Report.md
      • 施策の分析レポートをMarkdownで作成し、PRベースで管理していく
      • Report.mdを先に作ってサイクルを決める

まとめ

  • 仮説の実行から学びを得るサイクルを先に設計する
  • 前から逐次体に行わない

クックパッドクリエイティブワークフロー

Cookpadは1サービスを作るのに140人のエンジニアがいる

  • ユーザーのシーンごとにGroup分けしている。

料理きろくのアプリ版チーム

  • Missionオーナー
  • デザイナー
  • エンジニア ✕ 2
  • エンジニアとデザイナーがお互いを補完する

目的と仮説を明確に

  • 常になんのためにしているのか意識する

Github issueでのアイデア発散

デザインレビュー

  • 目的・背景・コンテキストを明確化
  • 職種関係なく、横串でデザインを評価する
  • 品質向上

数値は全員が見れる場所に

テスト

  • 考慮漏れ・見つめ直す
    • TsuyoiUI・・・社内のチェックツール
      • issue作ったら、issueテンプレートに自動的に反映する

リリース・分析

  • あの時誰かがしてたな???(゜゜)問題
    • チーム内外の共有をすぐしたい
  • Report.mdの誕生
    • 見たい時にすぐ見れるレポートの管理

デザイナの役割

  • デザインリリースマネージャ
    • リリース単位で体験やUIの変更箇所を把握、デザイン周りを一貫してみる役割

What/How to design test automation for mobile

テスト自動化について

  • 開発サイクルの効率化?
  • 自動化がモチベーション?

テストで話が噛み合わないところのコミュニケーションの方法

SPLIT がキーワード

-よくわからないものを分割していく

Scope

  • どこをテストの対象範囲とするか?
    • モバイルアプリを使っているユーザー
    • どこまで踏み込んでいってテストをするのか?

Phase

  • 開発中?orリリース後?
    • in Production
      • 世に出したあとのテスト
        • A/Bテスト
        • カオスエンジニアリング

Level

  • なにをテストするのか?
  • どこを自動化するのか?

sIze

  • テストの種別

    • UnitTest
    • IntegrationTest
    • ...
  • テストサイズを分割する

  • どういう形に落とし込んでいくのか?

Type

  • テストを目的別に区分

範囲、時間的なもの、どこまでするのか、どこまで自動化するのか?にどんどん分割していく。

Cookpad Android for Globalでの事例

  • 事前のコミュニケーションが大事
    • 理想的なプロダクトのラインを決める
  • Scope事例
    • ユーザーが実際に使う状態に近しい環境
    • ネットワークが関係する環境のテスト
  • Phase
    • in developent
      • 開発中だった
      • sizeを再定義 3つから4つ
        • UnitTest
        • IntegrationTest
        • UI Components based
        • User Senario based

iOSはパフォーマンスをテスト自動化しようとしている

  • 以前似たような状況にあって、パフォーマンスが劣化した例があった。

Rubyの会社でRustを書くということ

CookpadRubyの会社

  • 多くのサービスがRuby on Rails
  • 但し全てのサービスがrubyで書かれているわけではない
    • Middlewareなどはjava、Goで書かれてたりする
  • CookpadRubyの会社だけではあるが、Rubyだけの会社ではない。

Push通知を配信基盤をなんとかする

  • 都度配信

    • イベントごと
  • 一斉配信

    • 特定層に一斉配信

Rustで書き直す前のPush通知配信基盤とは?

  • 殆どの部分をアプリケーションが担っていた。
  • 基盤というにはあまりに機能が少なすぎた

もともとは世界最大のRailsアプリケーション

  • Pushするアプリケーションは1つ以上にある
    • しかし今はマイクロサービス化が進んでいる。
    • 1つのときは基盤が貧弱でもなんとかなった
    • 同じロジックが色んなアプリケーションにコピペされている。
      • DBを共有することは避けたい
      • DBに接続することも避けたい

新規版では全てのステップを配信基盤で担う

  • UserId指定
    • 配信先を受信設定に基づいてfilterする
    • Push通知の配信見積もり

厳しい性能要件があるアプリケーションをrubyで書くのはしんどい

  • Rustには色んなメリットがある。
    • 型、安全性、並行性
    • トレイト
    • データ競合のあるロジックはコンパイラが起こってくれる

Rust is not magic

  • Rustで書いたからと行って勝手に高速になるわけではに。
  • 早いソフトウェアを書くのはプログラマ市議

Facebookのデータローダの考え方を使う

  • クエリをまとめる

OSSを開発

github.com

github.com

※ ここからはさきは説明形式なのとrustなので詳しくわからず

  • ブロッキングな処理をFutureに変換しているとみなせる
    • JSのプロミス的な概念

Rustのいいところ

  • マルチスレッドが安全

    • マルチスレッドとイベントループを混ぜ込むみたいな複雑なアーキテクチャも採用できる。
  • とりあえずロックとかなくなる

  • 安心して高速化
  • 型安全、強力

cookpad storeTV 〜クックパッド初のハードウェア開発〜

StoreTVは三者にメリットがあるサービス

  • スーパー
  • ユーザー
  • 食料品メーカー

ハードウェアでも改善サイクルを回していく - ユーザーにあててサイクルを回す

サイクル

  • 第1サイクル
    • 最小価値影響
      • 売り場で料理動画を探す
        • 料理動画を探す・見れる
        • 300台配布
      • キッティング
        • 1台10分
        • 週ごとに料理動画を作った
    • 価値検証
      • 電話調査
        • 動画見てて楽しい!
        • 自分の作りたい動画探せる!
      • アプリの利用ログ
      • 売上 -> Posデータの提供を受けた
        • StoreTVの採用した売り場は他の売り場の1.3倍の効果アリ
    • その他の問題
      • 動画の数
        • 注力商品のみで良いと思っていた
          • 売り場にあってない
      • 見た目の問題
        • 目立たない
      • キッティング
        • 手作業が手間
      • 端末管理
        • アプリの更新が手作業
  • 第2サイクル
    • スケール
      • なにをやって、なにをやらないか
      • 得意なことは自分たちでやる、不得意なことは誰かに任せる
    • 動画の数
      • 毎月100本
    • 見た目
      • 不得意
      • ケースを作成する
        • 業者に依頼
          • 中国製
          • 中国に行ってきた
            • ロゴがバグってるw
      • 不得なことは1人でやらない、でも任せっきりはだめw
    • キッティング
      • 不得意
        • 業者に依頼
          • どうしても人力に頼らざる得ない
            • アプリケーションを整えた
    • 端末管理
      • 不得意
        • 自動アップデート
          • MDMによる一元管理(Mobile Device Managiment)
    • 問題点
      • サイネージサイズ
        • 大きすぎる
          • 売り場に置けない
      • 開発新興
        • バグが増え始める
  • 第3サイクル
    • 収益化
      • 広告配信の基盤開発
      • 広告接触者数のカウント
    • サイネージサイズ
    • 開発進行
      • 長時間安定して動画
      • バグの検出
        • 時限製のバグが発覚した
          • コードフリーズ後の長時間再生
      • 顔認識の機能
        • 端末計算リソースを食う
        • エグザイルを利用したww
          • なお、エグザイルに1台やられたww

Challenges for Global Service from a Perspective of SRE

クックパッドのグローバル・サービスってなに?

  • 海外向けのレシピサービスを提供している
    • 22言語68カ国で提供
    • イギリスで提供している

2017年のグローバルサービスの成長

  • 対応言語数
    • 15->22言語
      • 7言語の増加について
        • 全言語対応 ≠ 世界対応
        • 去年のスライド見てね

techconf.cookpad.com

現状の課題や挑戦

  • 特定の国のユーザー体験が悪い

    • 国ごとに差が出始める。
      • 原因がわからないと改善できない。
  • 世界中のユーザー体験を測定する

    • CatchPointを利用した。
      • CatchPoint Systemsのメトリクスを利用した
    • 原因を調査できるようになった。
    • インドネシアと米国で比較
      • TLS接続
      • Time to First Byteが遅い
      • -> 米国からの距離が遠い。
        • Cookpadのグローバル版は米国リージョンにある。
    • データセンターをユーザーに近い場所に移動
      • マルチリージョン化
        • しかし管理コストがかかってくる
    • CDNの導入
      • Fastlyを導入
      • 米国から遠い国のユーザー体験が改善
  • イベントのバリエーションが多い
    • ex.
      • アルゼンチンは独立記念日パステリートというお菓子を食べる
      • 日本だとバレンタインの時にユーザーが増える
    • 展開国が増えるとイベントバリエーションが増大する
      • SREは「毎月バレンタイン」
    • 課題改善
      • Amazon Auroraを導入
        • オートスケーリング
      • Dockerアプリ開発環境の提供
        • ECS + hakoでのデプロシステムの導入
        • hako-consoleを使って状態を管理
          • 日本で培った技術をグローバルに応用
  • デプロイのオペレーションコストが高い
    • ネットワークが安定しない、日常的に停電が起きる国とかある。
      • デプロイを他の人に依頼する問題
        • 世界中どこからでもデプロイ出来るようにする
        • 米国にデプロイサーバーを用意
          • デプロイサーバーでのマニュアルオペレーションの課題もある
    • 改善策
      • slackによるbotデプロイ
  • toilが急増する
    • toilとは?
      • 骨の折れる業務
      • アカウント管理業務とか
    • SREの対応する依頼業務が増大
      • toilの割合が増大
      • SREが本来したい業務ができなくなった
    • 世界中に社員がいるからこその課題。
    • アカウント管理
      • nginx + omniauth
      • アカウント管理のセルフ管理化(移譲)
    • SREのマルチリージョン対応
      • 時差の壁を超えたりとか

動き出したクックパッドのCtoCビジネス

  • komercoの発表
    • もので毎日の料理を楽しくするプラットフォーム
      • 料理を盛る器や鍋がいいと、もっと料理が楽しくなる

komercoにはサーバーサイドエンジニアがいない

  • サーバレス
  • Firebaseで開発している

(このあたりやたらFirebaseの宣伝というか、いいこと話してること多かった)

※ Firebase Japan User Group入っておこう。

firebase.asia

OpenSourceにすること

  • 少人数で品質を担保するため
    • Opensourceすると品質が向上する
    • 外部の人がチームのリソースになる
    • 再利用できる
      • 他チームで利用できる

技術一覧はこちら

Pring

  • firebase Model framework

github.com

Orderable

  • Order processing framework

github.com

開発の高速化の先になにがあるのか?

  • 大胆な戦略変更
    • 複数回の仕様変更
    • エンジニアが消耗しない
    • コミュニケーションコストがかからない
    • たくさん試すことができる
  • 事実は我々の中にない、市場に聞くべき
  • たくさん試すべき

Solve "unsolved" image recognition problems in service applications

画像分析のお話

昨今の画像分類問題

  • 理想的な状況下では「解けた」と言われている
    • 適切なラベルの付与
    • 適切なカテゴリの設計
    • closed set
      • 現実世界はopen setである
      • ラーメンの画像分析にケーキの画像がくることなんて容易にある。
  • 私たちが本当にときたい問題はなんなのか?
  • 解くべき問題の多くは「間違っている」
    • 本当に時対問題をtry and errorで探していく

料理きろくの進化と現在

  • 機械学習の観点から見る重要な点
    • クイックスタート
      • 要素技術が成長している
    • モデルの改善と苦手なカテゴリの考慮
      • 間違いやすいやつら
      • 植物はサラダと分類される
      • テストデータの拡充
      • 局所性を取り込むためのpatch化
        • 画像の一部だけに料理が移っていた時
        • ふと、お店で出てきた画像とかどうするんだろう?
          • 自分で作った料理ではなさそう???
          • それは分類されてもいいのかな???
    • 料理きろくのその先へ
      • 勝利写真のレシピカテゴリに分類
      • 単純な分類に見えて実は非常に難しい
        • openset における予測
    • 類似カテゴリをどう予測するか
    • 類似画像に対する分類

類似モデルは生まれるのか?

  • カテゴリを設定した時にどういう画像が生まれやすいのか?

モバイルへの移植

  • どうサービスに載せるか
  • 次に来そうな領域

Beyond the Boundaries

※ 基調講演

  • 技術を正しく理解し、「ふつうに使う」
  • 技術スタック
    • web
    • mobile
      • Swift
      • Kotlin
      • プロトタイピング
        • React Native
        • Firebase
    • Infra
      • AWS
      • docker
      • Hako
  • 自分たちの道具は自分たちで持続可能にする
    • コミュニティへの還元
  • 「境界」を認識し、乗り越える強い組織へ

まとめ

2年ぶりにCookpad Tech Confに参加してきました。
領域としてはプロダクト作りからグローバルでのサービス展開、機械学習まで幅広い話が聞くことができました。
個人的には、SREの話やPush基盤作りの話が面白いなーと感じましたが、HTTPやCookpadのプラットフォーム作りの話をもう少し聞いてみたかったと思いました。

HTTPリクエストでReferrerを送信しない

Referrerの制御方法について調べたので備忘録です。 下記ページを参考にしてましたがIE11での挙動など自分で追加で調査した箇所があるので付け足して行きます。

qiita.com

Referrerとは?

HTTPリクエストを投げたときの参照元です。
ブラウザがHTTPリクエストを投げる時、Referrerヘッダーに参照元(元いたページ)のURLが入ります。

Referrerヘッダーを制御する意図

特定のページ上でSNSウィジェットだったり、Youtubeウィジェットだったり、外部サイトの情報をiframeで埋め込むことは今時のウェブサービスであれば使われている画面が数多くあります。
しかし、このAPI呼び出しをする場合でも外部サイトへのリクエストとみなされるのでブラウザの開発者ツールで外部サイトのリクエストの中身を見ると Referrer: ヘッダーに参照元(元いたページ)のURLが表示され、Referrerヘッダーに乗って、外部サイトにURLが送信されます。

例えば、URLが非公開URLであったり、ワンタイムでなく時限token付きURLであった場合、外部に漏れては行けない情報が漏洩する可能性があります。

こういう時、セキュリティ上のリスクを抑えるため、参照元ページのページ情報を Referrer: ヘッダーに乗せずにリクエストを送信しないといけなくなります。

これはReferrerを制御する意図です。

制御方法

イマドキのブラウザ

イマドキのブラウザと古いブラウザで対応方法が異なります。

今時のブラウザ

などは最初に記載した参考のQiitaの記事の内容で大丈夫です。

<meta name="referrer" content="no-referrer">

こいつをheadのmetaタグに入れてやれば、Referrerは送信されません。

しかし問題があります。
このmetaタグの content="no-referrer" はIE11では使えません。

つまり、IE11でアクセスされたら上記のmetaタグを埋め込んでいても、Referrerが送信されて情報が外部サイト漏れます。

参考: https://webtan.impress.co.jp/e/2015/04/14/19750

IE11対策

IE11を始めとした古いブラウザには以下で対応します。

<meta name="referrer" content="never">

support ブラウザを調べる

以下で調べられます。

Can I use... Support tables for HTML5, CSS3, etc

確認したいブラウザにカーソルを合わせてみると使える contentを知ることが出来ます。

IE11の場合

f:id:ema_hiro:20180204030004p:plain

Edgeの場合

f:id:ema_hiro:20180204030018p:plain

(Edgeも対応してないんかい!!!!)

まとめ

Referrerを使った脆弱性について調べることができました。
何気なく使っているiframe埋め込みでも使い方次第では脆弱性になるので、ブラウザのサポート状況は常に確認する必要がありますね

(ほぼ)初めての自宅(リモート)作業をしてみた話

注) プログラミングネタではないです。

自宅作業の経緯

職場でインフルエンザが流行し、感染防止のために学級閉鎖の如く、所属している部署全体で自宅作業推奨になったため、期せずして自宅作業をする機会を得ました。
リモートで仕事するのはほぼはじめてだったので、実際にやってみて感じたこと、工夫したことをまとめました。

※ これは職場の緊急的な措置で、決してこの状態を肯定しているわけでも、期待しているわけでも、リモートにすべきだみたいな意見を持っているわけはありません。ただ、個人としては少しワクワクはしていました(笑)
※ なお、普段は基本的に出社するのがルールになっています。

自宅作業時期

1末〜2頭の3日間。
※ 本当は4日の予定でしたが最終日は予定があったので出社しました。

さまり

先に結論を述べておくと、僕個人の感覚としては、「やっぱり仕事は会社でしたい」ということを再確認しました。
エンタープライズ向けサービスの企業ではリモートが推奨されてますし、世の中の流れとしてもリモート推し的な空気を感じますが、個人の感覚としては会社の方が生産性が上がると感じます。
これは僕の主観なので、リモートの方があっている人ももちろんいると思います。
ただ、やはり100%リモートにするには色々超えないと行けない壁が大きい気がします。

ちなみに、リモートで業務をしてみて、仕事をする上でよかったことや、普段と違うことで気づいたこともありました。
仕事をする上でにリモートも選択肢としてあるのはプラスなことだと思いました。

リモートをしてみて

  • よかったこと
  • わるかったこと
  • 気づき/工夫したこと

よかったこと

通勤時間分寝れる

重要です。起きた時に「あ、そうか今日いかなくて良いんだ」って思って30分余計に寝ました。(起きろよ)

ひたすら自由

会社は公共の場なので、当たり前ですが周囲に気を使います。
それがないのでストレスフリーでした。
ジャージや寝癖のまま仕事しても誰もに文句言われませんし、誰かの目を気にする必要もありません。(ただ、この弊害はあります。後述します。)

細切れ時間を有意義に使える

ビルドしている最中やテスト回している間だったり、チャットのレス待ちのちょっとした時間に洗濯機回したり、食器洗ったり、掃除機かけたりしてました。
会社にいると、手持ち無沙汰の時間にコーヒー買いに行ったり、スマホゲームでガチャ回したり、ニュース見たり、Twitterしたりと、あまり「生産的でないこと」に意識をもってかれてますが、家事をすると少し生産的なことをした気分になって良いです。

自宅に引きこもるのでエコ

僕は基本家にいると決めた時はずっと引きこもるのでほぼ自炊です。
光熱費はかかりますが、外食したり飲料水買ったりするお金を使わずに過ごせるので、僕にとっては非常にお財布に優しくエコでした。

わるかったこと

メリハリつかない

多分、僕がリモートに向いてない理由の1番はコレです。
生活の延長で仕事しているので、よく言われるようにメリハリつかないです。
なんかダラダラしてるなーって感じることがありました。
今回は4日間限定だったので、なんとかなりましたが、これ、ずっと続いたら確実に自分はサボり始めると思いました。

プライベート見られるのはいい気分はしない。

オンラインMTGでビデオ通話したんですが、インカメで部屋の一部が映るのはあんまりいい気分しませんでしたw
こういうとき書斎とかあるとすごくいいんだろうなー。

(たぶん)太る

手の届くところにご飯やお菓子があるので、ひたすら何か食べながら仕事してました。コレ続けたら多分太ると思います。

気づき/工夫したこと

ここからは個人の感覚レベルでの気付きや、工夫したことを書き出します。

身だしなみは整えたほうが良い

寝間着でデスクに座ってもなにも始められません。
顔洗って、髭そって、着替えましょう。
コレだけで大分違いました。

家事大事

お昼ごはん作ったり、細切れ時間に洗濯もの干ししたり、業務とはコンテキストが全く違うことをするのでいい意味で頭の切り替えになります。というか勝手に切り替わります。
職場だと昼時にもネットニュース見たりとか、中度半端にエンジニア脳が残るので、実はこれ、脳のエネルギーを無駄に消費しているだけなんじゃないかって思いました。

オンラインMTGは十分MTGになる。

ハングアウトでオンラインMTGしたんですが、もうこれ十分MTGになりますね。
オンラインMTGの進歩を身をもって痛感しました。
段取りをちゃんとしてもらったというのもありますが、別にその場にいなくても会議はできるもんですね。
(ただ、インカメは大敵ですw👆上述)

ちょっとしたコミュニケーション大事

お昼行く時にslackに「昼行ってきます〜」と書いて、戻ってきたら「戻りましたー」と書いて自分のステータスをちゃんと伝えること大事だと思いました。
不要な憶測や不信感軽減のため。

お昼ご飯に行く

f:id:ema_hiro:20180202030033p:plain

お昼ご飯から戻る

f:id:ema_hiro:20180202030037p:plain

※ 同部署にいるyoichiroさんにリモートで働く上での教訓を聞いていたので意識的に行いました。

ちゃんと説明するようになる

基本チャットしかコミュニケーションツールないので、自分のステータスをちゃんと説明するようになります。(上述の内容と少し被りますが。)
会社にいると対面・口頭確認に逃げられますが、リモートだとそれが効かないので、冗長でもちゃんと説明するようになります。
ただ、神経使いますし、チャットするだけで疲れちゃうなーってこともありました。
ここらへんは慣れなのかもと思いますが、ぶっちゃけあんまり意識してなかったツケですね。普段からもっと丁寧にコミュニケーションしとけよっていう話でもあります。

当たり前ですが、コミュニケーションって大事。 とはいえ、やはりチャットだけだと100%意図伝えきれないこともあるのかなーと感じて、会社で対面でコミュニケーション取った方が文章だけのコミュニケーションよりストレスレスだし、意思疎通は格段に速いと思います。
(言葉遣いにとかに対して厳しい人だと余計に疲れそうな気もします。)

椅子にはお金をかけたほうがいい。

自宅にはアーロンチェアを入れてます。同僚でも自宅の椅子が劣悪なのでやはり出社しますという方がいて、リモートするなら自宅の設備投資はマストだと感じました。

通勤時間が気分転換になるんだなーと再認識

僕には通勤時間にぼーっと景色眺めてたりするのが案外気分転換になってたんだなーって再認識しました。
会社にいかないとそもそも外に出ないので、それはそれで精神衛生上よろしくないなと。外の空気は吸ったほうがいいという教訓。
(※ 完全に個人的な感覚です。)

結論

最初にも述べましたが、やっぱり自分には会社の方が仕事するにはあってる気がしました。
理由はコミュニケーションコストと仕事モードへの切り替え。

やはり、対面のコミュニケーションによるスピーディーな意思疎通をリモートでは超えられないと思いました。
また、個人的には場所が仕事モードに切り替わるための重要な要素だったので、自宅のままだとどうしても勢いが出ませんでした。

ただ、リモートしてみて普段自分があんまり意識してなかったことにも気づけたこともありました。
リモートでの綿密なコミュニケーションだったり、通勤ストレスなかったり、ちょっとしたコミュニケーションの重要性認識したり。

働き方改革が標榜されてるからか、会社にいかないと仕事できないなんて時代遅れだ!リモート導入しろ!的な会社にいかないことが正であるみたいな空気を感じるのですが、実際にしてみた身としては、制度うんぬんの問題というよりも、個々人の状況に応じて取りうる選択肢に幅があることが大事なんじゃなかろうかと思いました。
いつもは会社に行くけど、たまにのっぴきならない理由で出社できなかったり、休むほどでないけど、風邪っぽくて周囲に感染させるのを防止させるために自主的に自宅作業にしたり、その他家族の問題があったりと、色々な理由があるときにリモートもいいよって言われるとすごく心理的に楽だろうなとは思います。実際そういう声聞くし。
(まぁ、書いてる僕自身は独身ひとり暮らしなので、ここらへんはあまり優先度上がってこないことではありますがw)

あんまり極端でどちらかに寄った意見ばっかり目にする機会が多いので、もっとその中間というか、時と場合によってどちらも選べるよみたいな考え方が広まっていくと良いと思いました。