しょ〜うぃん広場

おもにTech系なブログ、ときどき個人的なブログ

Team of Teams を(途中まで)読んだ

2018年は3週間毎に技術の勉強と、組織/マネジメントの勉強を繰り返す予定を立てていますが、1月21日~2月10日は後者の勉強期間です。 (1月1日~20日はVue.jsを勉強してたのですが、思ったより時間がかかっていて終わってません…)

2017年末から TEAM OF TEAMS (チーム・オブ・チームズ) を読んでいたので、今回の勉強期間ではその続きから読むことにしました。 全体の55%ぐらいしか読んでいないですが、簡単にまとめます。(途中で諦めた理由は後述)

本の概要

本の主張としては「トップダウンでマネジメントしていく従来の方法では、変化が激しくより複雑である近年の課題を解決するのは難しい。下部のチーム/個人に十分な権限を与えて主体性を持って行動させることによって、それらの課題を解決することができる。」というものであったと思います。

この主張の正当性を主張するために、米軍とアルカイダの戦闘の例や、NASAアポロ計画についての事例が取り上げられています。(こういった事例の紹介が本のほとんどを占めていたため、残りの45%は読むのをやめてしまいました。。実は後半の方が大事だったりして…)

米軍とアルカイダの戦闘の例を紹介すると、 米軍は過去の成功体験から、ピラミッド型のトップダウンな組織で構成されており、各チームにはプロジェクトの目標とそれに関する必要最低限の情報のみが与えられている状況でした。 そのためあるプロジェクトの途中に他のチームにとってはとても貴重である情報を見つけたとしても、その価値が分からずに見逃してしまい、与えられた目標のみを追いかける内に向いた組織になってしまっていました。 一方でアルカイダは、末端の戦闘員までアルカイダの最終目標を認識しており、それを達成するために全員が同じ方向を向いて、目標達成のために何をすべきなのか自分で考えて行動するような組織構造ができあがっていました。 (個人的には「ピラミッド vs WWW(ワールドワイドウェブ)」な対象的な組織構造だと感じました。)

そのためアルカイダの幹部を暗殺しても、組織全体が方向を見失い壊れてしまうようなことはなく、アルカイダの撲滅には苦労したようです。 また毎回目標や戦略が上から降ってくる形になっていた米軍は、その間に戦況が変わっていてそれが全く役に立たないものになっている場合もあり、素早い状況の変化に対応できない構造になってしまっていました。

そこで、米軍は「チームの中のチーム」という方針で、配下のチーム同士の関係が単独のチームの内でのメンバー同士の関係に似た組織構造を作ることにしました。 つまり今までは上下関係の間でのみ情報共有がなされていましたが、方針の転換によりチーム同士の横関係の間でも情報共有が許されるようになりました。 情報共有についてだけではなく、役割、意思決定権限、リーダーシップに関しても、従来とは全く逆の手段が導入され、アルカイダと同じように末端のチームで意思決定が行われるようになったのです。


この本は、某なんとかStationというゲーム機を作っている会社のマネジャーさんにオススメされて読み始めた本なのですが、某社ぐらいの大きな組織だと、この本から学ぶことは多いのかもしれないと感じました。 私自身大きな組織に属したことがないので、ピラミッド型組織の課題感を肌で感じたことがないのですが、これから弊社が大きくなっていく中でどういう組織構造を作っていくべきなのか、少し明確になった気がします。

組織/マネジメント勉強期間はあと1.5週間あるので、昨日から 新1分間マネジャー という本を読んでいます。こちらは薄い本なので、1時間で60%ぐらい読んでしまったのですが、マネジメント素人にはこちらのほうが学びが多いです(笑) こちらも読み終わったらまとめ記事を書こうと思います。

Regional Scrum Gathering Tokyo 2018 に参加してきました

気分が良いので、1日で2記事書きます。笑

1月11,12日で Regional Scrum Gathering Tokyo 2018 に参加してきました。 イベント自体は13日まであるのですが、2日間で得た学びが多く、これ以上インプットすると頭が弾けそうだったので、2日でやめておきました。

参加したきっかけ

弊社 scouty では複数人開発が始まった2017年10月からスクラム(っぽい)開発を始めています。 開発メンバーはだれもしっかりとしたスクラムでの開発経験がなかったため、始めの一ヶ月半ぐらいスクラムの経験が豊富な外部の方にアドバイザーとして入ってもらっていました。

プロセスの改善を続けて、最近では落ち着いてスクラムな開発ができるようになってきたのですがまだまだ不安な点もあり、ちょうど関わりのあった eureka の @kajinari さんに相談したところ、このイベントを紹介してもらいました。

イベントで学んだこと

聞いていた発表はだいたいTwitterでリアルタイムまとめをしていました。 #RSGT2018 showwin で検索するとみれます。

twitter.com

自分的に良いなと思ったものをいくつか列挙すると、

これは1日目のKeynoteの内容なのですが、会場でも頷いている人が多かった話でした。 今回のイベントでも、これ帰ったら試してみよう!というものがいくつもあった(後述)ので、 うまくいくかわかりませんが自分のチームで試してみたいと思っています。

Run the experiment !!


(スレッド機能でつなげてかいていたので、前のツイートも表示されてしまっています)

サイボウズさんで、ウォーターフォールからスクラムに切り替えたことで得られたメリットの話です。 うちのチームではまだまだこれらのメリットを享受できていないので、こうなれるようになりたいなと強く思いました。

・残業がほとんどなくなった

(発表では触れられていませんでしたが)ベロシティが上がっているように見えているけど、実は残業時間が増えているだけだった、ということが起きうるなと自分で勝手に思っていました。

スプリントレビューの時にベロシティの確認と一緒にチーム全体の残業時間を確認してみると面白そうなので取り組んでみます。

・スプリントの計画を達成した後のんびり過ごす (空いた時間でKAIZEN)

に関しては、いろいろと思うことがあります。

私はスタートアップ(scouty)で働いているのですが、完全に同じことをしている競合は今のところいないため、先行優位性を活かして(なるべく早く製品を成熟させ)今のうちにマーケットを取りに行きたいという会社としての思いがあります。

そのため、今スプリントの計画を達成したら、次スプリントのバックログからタスクを引っ張ってきて新しい価値の提供に取り掛かりたいのです。 そしてまた、そうすることでのみチームのベロシティが向上していることが測れるのでは?とも思います。

一方で、その方法ではスプリントの計画を早く達成しても何のアメ(ご褒美)も与えられず、高いモチベーションを保って開発を続けるのは難しいとも感じます。 KAIZEN系のタスクを定義してスプリントに突っ込むのは、"やらされてる感"があってちょっと違うなぁとも思い。なかなか自分の中で納得いく答えが出ません。 (私も"やらされてる感"のある仕事って大嫌いなので、ちょっと空き時間に「ちょっとこのページの描画遅いと思ってたから高速化しといたよ🤤」みたいなことをしたいんですよね。。)

ここは組織の状態によって答えが違う部分な気がするので、POとちゃんと話し合う必要がありそうです。

・ペアやモブワークを行うことが多くなった

この発表に限らず、いろいろな人と話していても、うちでも取り組んでいるよ。という話をよく聞きました。 スクラムガイドには、開発チームの特徴として

• 機能横断的である。インクリメントを作成するスキルをチームとしてすべて備えている。
(略)
• 開発チームのメンバーに専門能力や専門分野があったとしても、最終的な責任は開発チーム全体が持つ。

とあり、開発チーム全員が共通なスキルセットを持ち、どのタスクでもこなせることが理想であると書かれています。 そのために、みなさんスキルトランスファーを目的として実施しているようでした。

その他にも複数人で開発することで、タスクを誤解していてレビューされてやり直しになる、のようなことも起きなくなり、レビュー済の状態に近い精度で開発ができるメリットもあるとのことでした。

弊社でも、ネット上の不定形/非構造なデータを扱っていることや、(機械学習まではいかないレベルの)複雑なドメインロジックの実装が多いこともあり、タスクによってはレビュー→差し戻しが多く発生するものがあるため、そういった難易度の高いタスクに関してはペアワークをすることで開発効率があがるかもしれないと思いました。


これについては私も同意で、技術が発達したことにより高い専門性を保つためには、多くの時間を学習につぎ込まないといけない世の中になっていると思います。

個人的には、バックログのうち8~9割ぐらいのタスクについては全員ができ、他プロダクトとの優位性に関わるような1~2割の部分は高い専門性をもった人しかできなくても仕方ないと思っています。 むしろその1~2割ができる稀有な人材を確保できているからこそ、その組織が他に勝てるのではないでしょうか。

弊社では採用基準の一つに「既存のメンバーが持っていない特長(スキル)をもっていること」というものがあります。当然人が増えていくにつれてこの条件を満たすのは難しくなっていくため、どこかでこの条件を諦めないといけなくなるフェーズは来ると思っていますが、なるべく長く続けていき最強のチームを作りたいと思っています。

今回答えがわからなかったところ

私自身 SCRUM BOOT CAMP THE BOOK を読んで、イベント中に スクラムガイド の存在を知ったぐらいの勉強不足スクラム初心者なので、CSMの研修などを受ければわかるようになるのかもしれませんが、デイリースクラムのフォーマットの価値が未だによくわかっていません。 スクラムガイドには

• 開発チームがスプリントゴールを達成するために、私が昨日やったことは何か?
• 開発チームがスプリントゴールを達成するために、私が今日やることは何か?
• 私や開発チームがスプリントゴールを達成するときの障害物を目撃したか?

を共有すると書かれています。「輪になって口頭で共有する」とは書かれていませんが、イベントに参加してこのようにやっているチームが多いように感じました。

弊社では、上記2つについてはデイリースクラム前にSlackで各自文字ベースで報告するようにしており(そもそもKANBANを見ればわかる)、デイリースクラムではBurndownが予定通りかと、障害物がないかの2点のみ確認するようにしています。それにより時間短縮ができ、Burnが予定どおりではなかった場合に、小さなふりかえり/スプリント計画をデイリーで行えています。

デイリースクラムの目的が "スプリントゴールを達成するため" であれば、単なる報告会よりもこちらの方が有効な気がしているのですが、どうなんでしょうか。 答えをお持ちのスクラムマスターな方々 @showwin にツッコミ頂けたら嬉しいです! (答えを頂いたので最下部に追記しています)

帰ったら試すもの

  • スプリントレビューでベロシティと一緒にチーム全体の残業時間を確認する
  • 複雑なタスクはペアワークで取り組み、生産性があがるのか、働き方に対する満足度が上がるのか確認する
  • スプリントレビューで機能開発タスクとバグ修正タスクの比率を確認する (長期的に見て70%機能開発が理想)
  • スクラムイベントのファシリテートを別の人にやってもらう (スクラムマスターがでしゃばりすぎず、開発チームにも主体的に動いてもらうために、一度経験してもらって何か変化があるのかみてみたい)
  • POもリファインメントに参加する。(現状開発チームがメインでリファインメントしているが、タスクの定義が曖昧なものもあるので、事前にPOに行ってもらう)
  • リリース可能かどうかはPOが判断する。(POが忙しいので、SMの私が品質の確認もしてしまっている状態)

代表がPOをしているのですが、経営に集中させたいので、(エンジニア社員が増えたら)そこからPOを任せる人を別で立てないと、今のままでは役割を十分に果たせないなと感じています。

おわりに

Regional Scrum Gathering Tokyo 2018 の運営に関わっていた皆さん、ありがとうございました!とても勉強になったカンファレンスでした。来年も参加します!

繰り返しになりますが、イベントを紹介してくれた @kajinari さんありがとうございました!!

追記

@ryuzee さんと @haradakiro さんからデイリースクラムについてご意見頂きました。ありがとうございます!

上で私が参照していたのは、2016年7月版のスクラムガイドでしたが、2017年11月にスクラムガイドの改訂があったようです。

2017年11月版では、デイリースクラムの章に以下のような説明がありました。

デイリースクラムは、開発チームがスプリントゴールを達成する可能性を最適化する。開発チームは、自己組織化チームとしてスプリントゴールを達成し、スプリント終了までに期待されるインクリメントを作成できるかを毎日把握しなければいけない。
デイリースクラムの構成は、開発チームが設定する。スプリントゴールを目指している限り、他のやり方で行なっても構わない。質問を使うチームもあれば、議論ベースで進めるチームもある。たとえば、以下のような例を使用するといいだろう。
• 開発チームがスプリントゴールを達成するために、私が昨日やったことは何か?
• 開発チームがスプリントゴールを達成するために、私が今日やることは何か?
• 私や開発チームがスプリントゴールを達成する上で、障害となる物を目撃したか?

中身の例として上の3つが提案されている形になっており、 "開発チームがスプリントゴールを達成する可能性を最適化する" 方向を向いていれば他の方法でも問題ないようでした。

2017年の振り返りと2018年の目標

ブログの最後の記事を見たら2016年8月でした。

大学の同期が立ち上げた scouty にJOINした2016年11月から一度もブログを書いていないことになりますね。 1年以上もブログ書いていないとは思っていなかったのでびっくりしました…

今年はちゃんと書こうと思っているので、2017年の振り返りと2018年の目標から書いていきます。

2017年の振り返り

10月までは自分がほぼ一人でプロダクトの開発をしていたので、そこに全力コミットする事が多く、今まで勉強してきたことをアウトプットし続ける年でした。 下半期は採用活動に注力したこともあり、幸いにも10月2人、12月に1人エンジニアが入社してくださり、今では4人体制で開発しています。

高い開発速度を保ちつつも、後から入ってくるエンジニアのために、ドキュメント化や保守しやすいコードを書いていたつもりでしたが、 いざ人が増えると、ドキュメント化されていない属人化された知見が大量に存在することが露呈し、コードも保守性が低くDDDで書き直す大規模なリファクタリングを行うことになってしまいました。

10月からの2ヶ月間で大規模なリファクタリングも無事に完了し、最近では(比較的複雑なビジネスロジックが多いのですが)開発に必要な裏側のロジックへの理解も開発チームに浸透してきた感じがします。 2018年はさらに人を増やしつつも、彼らを中心に更に高速な製品開発ができそうで楽しみです。

2018年の目標

2017年はほとんどインプットせず(学んだのはPython, Djangoぐらい)、アウトプットばかりしていたので、今年はインプットメインで行きたいなと考えています。 目標は2つ設定しました。

input を多めにする

・3週間に1冊、技術本と組織本を交互に読む
・仕事以外のコードも積極的に書く

エンジニア文化の形成

・高い生産性、知識の共有、自発的な学習、自立性
・(e.g.) スクラム、ペアプロ、社内LT

勉強したい内容に関して、技術面では以下の3つを重点的にやっていきます。

  • 2017年の課題としてあがった、保守性/可読性の高いコードを書くためにデザインパターンの勉強
  • 今後プロダクトでVue.jsを使うことになるので、フロントエンドの勉強 (今のスキルセットはインフラ-バックエンドメイン)
  • 機械学習/自然言語処理 周りの基礎的な学習 (社内でWeb開発チームと機械学習チームのパイプ役をするため)

マネジメントや組織づくりに関しては、スクラムや強い組織づくりについて重点的に学び、開発チームが120%の力を出してプロダクト開発に取り組める環境を作れるようになりたいと思っています。

もう一つの目標として、エンジニア文化の形成があります。 scoutyでは採用の基準の一つに、「既存の社員に持っていない特長をもっていること」を掲げており、コードの設計に強いエンジニアや、DBにめちゃくちゃ詳しいエンジニアがいます。彼らが持っている知識を他のエンジニアに伝搬させていくことで、組織全体のスキルが底上げされ強いチームを作ることができると信じています。 そのためにもペアワークや社内勉強会などいろいろと挑戦してみて、良い文化を作り上げていきたいと思っています。

私は学生時代も前職も受託開発をしていて、今まで0→1で製品の開発経験ばかりしていましたが、今年は 1->10 あるいは 10 -> 100 にしていくフェーズのため、エンジニアとしても新たな課題にぶつかるでしょうし、(そもそも全く経験したことのない)マネジメントの業務も発生するので、2018年は大きく2面から成長できそうで楽しみです。

任意のSQL文で mysqldump できるツールを作った

現状

$ mysqldump --query '任意のSQL文' > mydump.sql

のような事をしたかったのだけど、mysqldump では --where オプションで

$ mysqldump mydatabase users --where 'id IN (SELECT user_id FROM hoge WHERE huga > 10) AND id > 1000'

ぐらいのことしかできず、キーが1つの場合の JOIN を IN に書き直せるぐらいが限界になる。

別の方法としては mysqldump を使わずに

$ mysql -e "SELECT * FROM users" mydatabase --xml > mydump.xml
$ mysql --local-infile -e "LOAD XML LOCAL INFILE 'mydump.xml' INTO TABLE users;" mydatabase 

とすると任意のSQL文が使えるが、XML形式でしか出力できないため大量のレコードを出力する際にはダンプのファイスサイズがかなり大きくなってしまう。中身はこんな感じ。

$ cat mydump.xml
<?xml version="1.0"?>
<resultset statement="select * from users
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
    <field name="id">1</field>
    <field name="first_name">sato</field>
    <field name="last_name">huga</field>
    <field name="age">19</field>
    <field name="country">JP</field>
    <field name="created_at">2016-08-13 08:45:58</field>
  </row>

myquerydump 作った

そこで showwin/myquerydump をつくった。 これを使うと

$ myquerydump mydatabase "SELECT * FROM users" > mydump.sql
$ mysql mydatabase < mydump.sql

のように export/import できる。 ダンプファイルの中身も mysqldump と同じように SQL で書かれているのでファイルサイズも大きくならない。

$ cat mydump.sql
LOCK TABLES `users` WRITE;
INSERT INTO `users` VALUES ('1','sato','huga','19','JP','2016-08-13 08:45:58'),(…
UNLOCK TABLES;

ファイルサイズを比較してみると、このようなテーブルの300万レコードで以下のようになる。

mysql> desc users;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| first_name | varchar(64) | YES  |     | NULL    |                |
| last_name  | varchar(64) | YES  |     | NULL    |                |
| age        | int(11)     | YES  | MUL | NULL    |                |
| country    | varchar(64) | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
mysql> SELECT COUNT(*) FROM users;
+----------+
| count(*) |
+----------+
|  3000000 |
+----------+

$ ls -lh
104M  users.mysqldump
104M  users.myquerydump
551M  users.xml

XMLで出力した場合と比べて20%弱ぐらいのサイズになり、当然だが mysqldump と同じぐらいになる。

便利オプションの紹介

例えば

$ myquerydump mydatabase "SELECT users.name, prefectures.name FROM users INNER JOIN prefectures ON users.prefecture_id = prefecture.id ORDER BY users.name" > my.dump
$ cat my.dump
LOCK TABLES `users` WRITE;
INSERT INTO `users` VALUES …
UNLOCK TABLES;

のように複数テーブルのカラムを SELECT してダンプを取る時には大抵 INSERT 先は users テーブルでなかったりするので、勝手に INSERT INTO 'users' とされてしまうと困る場合がある。 そういうときには -t オプションでテーブル名を指定すると

$ myquerydump -t user_prefecture mydatabase "SELECT …" > my.dump
$ cat my.dump
LOCK TABLES `user_prefecture` WRITE;
INSERT INTO `user_prefecture` VALUES …
UNLOCK TABLES;

となって便利。

INSERT 前にテーブルを空にしたい場合には -add-delete-table オプションを付けると DELETE FROM が追加される。

$ myquerydump -add-delete-table -t user_prefecture mydatabase "SELECT …" > my.dump
$ cat my.dump
LOCK TABLES `user_prefecture` WRITE;
DELETE FROM `user_prefecture`;
INSERT INTO `user_prefecture` VALUES …
UNLOCK TABLES;

残りの細かなオプションは README#Usage を見て頂けると良いと思う。 基本的には mysqldump と同じオプション名になるように気をつけている。

問題点

速度が遅い!! 上の300万件ある users テーブルでこれぐらいの速度差がある。

$ mysql -e "SELECT * FROM users" mydatabase --xml > users.xml
=> 14 sec

$ myquerydump mydatabase "SELECT * FROM users" > users.dump
=> 78 sec

ファイスサイズが5倍になる mysql -e --xml を使うか、ダンプに5倍の時間がかかる myquerydump を使うかという選択をしなければいけない感じでイマイチ…

もう少し高速化して2倍ぐらいの時間でダンプが取れるようにしたい。

Webサイトの負荷検証ツールを作ってみた

先週仕事で、負荷検証をしてみたいかも!みたいな話がすこし上がって、どんなツールがあるのか調べてみたら、最近は Gatling というのがちょっとアツいらしい。 昔から使われている(らしい) JMeter はあまりパフォーマンスが出ないとか書いてある記事を見かけたけど、ぼくは使ったことがないのでよくわからない。

Gatling はパフォーマンスを重視して Scala で書かれているんだけど、リクエストのシナリオを書くのに ScalaDSL を書かないといけない。こんな感じ

class MySimulation extends Simulation {

  val conf = http.baseUrl("http://example.com")

  val scn = scenario("Gatling")
      .exec(http("index").get("/"))
      .during(10 minutes) {
    exec(
      http("json").get("/json")
        .check(jsonPath("$.id")
        .saveAs("id"))
    )
  }

  setUp(scn.inject(atOnceUsers(5)))
        .protocols(conf)
}

複雑なリクエストを送りたい時には使い勝手が良いのかもしれないけれど、ScalaDSL とかよくわからないし、書きたくないので、もっと簡単に負荷検証ができるツールを作ってみた。

hakari

ツールの名前は hakari で、測りたいから hakari にした。 Easy to Install, Easy to Write Scenario. をウリにしていて、カップラーメンを待つ3分の間にインストールから実行までできてしまう。

インストール

$ brew tap showwin/hakari
$ brew install hakari

リクエストシナリオを書く

# scenario.yml
TopPage:
  method: "GET"
  url: "http://example.com/"
Login:
  method: "POST"
  url: "http://example.com/login"
  parameter:
    email: "user@example.com"
    password: "secret_password"

負荷検証実行!!!

$ hakari
2016/02/21 18:12:47  hakari Start!  Number of Workers: 2
2016/02/21 18:13:48  hakari Finish!
TopPage
    200: 125 req, 238.66 ms/req

Login
    200: 110 req, 255.11 ms/req
    500: 15 req, 192.18 ms/req

あっという間に負荷検証できて、ビックリする。
上の例では、2並列リクエストでテストを行っていて、1分間にトップページが125回リクエストされて、平均 238ms でレスポンスが返ってきたことがわかる。

デフォルトでは2並列リクエストで1分間の負荷検証を行うけど、もう少し細かな設定もできて、HTTP header をカスタマイズしたかったら

# myconfig.yml
Header:
  Accept-Encoding: "gzip, deflate, sdch"
  Accept-Language: "ja,en-US;q=0.8,en;q=0.6"
  Cache-Control: "max-age=0"
  User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.39 Safari/537.36"

と設定ファイルを書いて

$ hakari -c myconfig.yml -s scenario2.yml -w 10 -m 2

とすると、10並列リクエストで2分間 myconfig.yml に設定した HTTP header で scenario2.yml のシナリオを実行できる。

まとめ

hakari は Gatling や JMeter と比べると、結果表示部分のレポート機能がまだまだ弱いので、そこをもう少し強化する必要がある。逆に、レポート機能はそんなに充実してなくて良いので、手軽にどのぐらいのリクエストをさばけるのか負荷検証したいという場合には hakari を使うと良いと思う。

昨日の午後から開発し始めて、24時間でこのぐらいのツールが作れてしまうので、Go 言語はすごい。 ぼくはすごい Gopher ではないので、テストコードも書いていないし、おそらく Go らしいコードも書けていない。。もっと勉強しなければ。

便利!! と思った方は、遠慮せずに GitHub Star ください!! → showwin/hakari

ネットワーク速度を計測するコマンドラインツールを作ってみた

ネットワークの回線速度を計測するツールspeedtest.net が有名ですが、これはブラウザからしか計測できません。 定期的に回線速度を計測して記録したい時や、世界中のサーバーに対してネットワーク速度を計測したい時に、これをブラウザで行うのは大変なので、コマンドラインからネットワーク速度を計測できるツールを作成しました。

速度の計測には speedtest.net の資産を使っていて、ダウンロード/アップロードをする計測先のサーバーは speedtest.net に登録されているものの中から選択することができます。

インストール方法

Mac(Homebrew) の場合

$ brew tap showwin/speedtest
$ brew install speedtest
$ speedtest
Testing From IP: 124.27.198.183 (Fujitsu) [34.7000, 137.7333]

Target Server: [6691]    58.53km Shizuoka (Japan) by sudosan
Latency: 28.030145ms
Download Test: ................
Upload Test: ................

Download: 60.31 Mbit/s
Upload: 22.61 Mbit/s

とあっという間に計測できます。 他のOSの場合には こちら にパッケージ化したものがおいてあるので、そちらを使ってください。

使い方

現在地から一番近いサーバーに対して速度計測を行います。

$ speedtest

サーバー一覧を現在地から近い順に並び替えたものを表示します。

$ speedtest --list
Testing From IP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
[6691]     9.03km Shizuoka (Japan) by sudosan
[6087]   120.55km Fussa-shi (Japan) by Allied Telesis Capital Corporation
[6508]   125.44km Yokohama (Japan) by at2wn
[6424]   148.23km Tokyo (Japan) by Cordeos Corp.
...
[4580]  2938.66km Ulaanbaatar (Mongolia) by Kewiko LLC
...

いきなり、モンゴルにあるサーバーとの回線速度を計測したくなっても、そのサーバーのIDを指定すれば簡単に計測できます。

$ speedtest --server 4580
Testing From IP: 124.27.198.183 (Fujitsu) [34.7000, 137.7333]

Target Server: [4580]  2938.66km Ulaanbaatar (Mongolia) by Kewiko LLC
Latency: 292.195371ms
Download Test: ........
Upload Test: ....

Download: 20.76 Mbit/s
Upload:  4.40 Mbit/s

意外と速いですね。

静岡と横浜と東京の平均値を計測したくなったら、複数のサーバーを指定することもできます。

$ speedtest --server 6691 --server 6508 --server 6424
Testing From IP: 124.27.198.183 (Fujitsu) [34.7000, 137.7333]

Target Server: [6691]    58.53km Shizuoka (Japan) by sudosan
Latency: 31.216696ms
Download Test: ................
Upload Test: ........

Target Server: [6508]   192.30km Yokohama (Japan) by at2wn
Latency: 16.12025ms
Download Test: ................
Upload Test: ................

Target Server: [6424]   208.44km Tokyo (Japan) by Cordeos Corp.
Latency: 15.109657ms
Download Test: ................
Upload Test: ................

[6691] Download: 60.06 Mbit/s, Upload: 24.17 Mbit/s
[6508] Download: 72.95 Mbit/s, Upload: 80.88 Mbit/s
[6424] Download: 69.51 Mbit/s, Upload: 75.39 Mbit/s
Download Avg: 67.51 Mbit/s
Upload Avg: 60.15 Mbit/s

便利ですね!!!

このツールすごいんですよ!

同じようなツールsivel/speedtest-cli というのがあり、こちらも speedtest.net のサーバーを使って同じように計測しているのですが、 speedtest.net の結果と比較してみると結構差がありました。 ぼくが今回作成したものは、ブラウザで speedtest.net を使って計測するときにかかる約半分の時間で計測が可能で、さらに既存の sivel/speedtest-cli よりも高い精度 (よりspeedtest.netで計測した値に近い) で計測することができます。 詳細が気になる方は 実験結果 をご覧ください。

これでネットワーク速度計測し放題ですね!!!

cookpad のオフィスに遊びに行ってきた

Facebookに 中国から日本に帰ってきた! って書いたら、去年のインターンでお世話になったcookpad人事の方に、「新オフィス遊びにおいでー」って言われたので遊びに行ってきた! (図々しくてすみません…笑)

写真撮ってくればよかったんだけど、忘れちゃって載せられる画像が1枚もない…笑

去年のインターンで一緒だった@s_osa_くんがバイトしてたから、ちょっと時間頂いて「研究しながら週四でバイトしてるよ〜(スゴイッ)」みたいな話とか聞いた。 (夕飯一緒に行けなくてゴメン、また今度行こう!!)

人事の方にひと通りオフィスの中をぐるっと紹介してもらって、なるほどなるほど〜って感じだった。 ワンフロア貸切だけど、全部が見渡せる感じではなくて、社員さんたちのスペースは大きく3つぐらいのブロックに分かれていた気がする。 (どのチームをどこに配置するのかってすごく重要だと思うんだけど、だれがそれ決めるの?って聞き忘れて残念だ…)

そのあとは @taiki45 さんと1時間ぐらい時間頂いてお話させてもらって、RailsのFat Modelはどう解決したらいいのか、E2EとかModelのテストってどこまで書いているのか、最近注目しているミドルウェアはなんですか?とかを聞いた。 大学は文系の専攻で、卒業して3年目でバリバリプログラム書いてる方みたいだったから、自分ももっと成長スピード上げていかないとなって刺激を受けた。

(cookpad は)リモートワークしないんですか? って聞いたら、抽象度の高い話はホワイトボードとかに絵とか図を書きながら議論した方が効率が良いでしょ? という回答をもらって、確かに自分たちもそれでちょっと困っていることはあるなと思った。自分は仕事でSlackとSkypeでしかコミュニケーションを取っていないから、自分の意見を伝えるのに必ず言葉にして発しないといけなくて、「こういう感じ」をうまく伝えられなかったり、「この辺がターゲット」をマトリックスのこの辺 みたいな形で伝えられないのは確かに弱点としてある。

あとは、グループ内のToDo管理もポストイットを使ったカンバン方式で管理していて、 これはなんでオンラインで管理しないんですか? と聞いたら、(ないと思うけど)だれかが cheat する可能性があるし、チームみんなでポストイットを囲んで、「このタスクは終わったよね」とか確認しながらタスク管理できるのが良いとのことだった。 自分の仕事では Pivotal Tracker + Slack でタスクに変化があれば、Slackに通知が来るようになっているけど、ドカドカっとだれかがタスク整理したりすると、何が起こったのか把握しずらいし、その辺りもリモートワークに改善の余地があるなぁと思った。

自分は大学を出てすぐにリモートワークをしてしまったから、良いチームがローカルワークでどうやって仕事を進めているのかの知見が少なくて、今回みたいな機会があるとすごく勉強になる。

インターンで5日間お世話になっただけなのに、1年後も覚えててくれてこういう機会まで設けてくれて本当にありがとうございます!圧倒的感謝!!! という感じなので、ブログの記事にしてみました。

また機会があれば、遊びに行かせてください〜!