5000164 is here
My writing is my life.
No results for undefined
Powered byAlgolia
謙虚・尊敬・信頼を忘れずにやっていきたい - 本「Team Geek ――Googleのギークたちはいかにしてチームを作るのか」の感想

前々から読みたいと思っていたのでついに読んだ。
HRT について、文化について、勉強になった。
謙虚・尊敬・信頼を忘れずにやっていきたい。

読書メモ

  • 人間は断続的なバグの大きな塊だ

    • 自分のバグを修正したかったらダメなところを気づかせてもらう
  • 自分がコントロールできる変数は自分自身
  • 謙虚・尊敬・信頼
  • HRT の文化を育んでいく

    • 文化がない状態では建設的な批判などができなくなる
  • 自分のやり方でやる、というエゴを通すために多大なコストを払う価値があるか考える
  • チームは個人の生産性や幸福に直接影響する
  • ソフトウェア開発はチームスポーツである
  • 個室が必要なのではなく、ノイズや邪魔を除外する

    • 集中したいときは集中できるようにする仕組みを作る
    • 特定の合い言葉やヘッドフォンやぬいぐるみで意思表示をするなど
  • もちろん集中したまとまった時間が必要だが、チームには素早い接続が必要
  • 過ちから学ぶには失敗を文書化する
  • チームには文化がある

    • 文化は創業者や初期メンバーが作った文化に新規メンバーが加わって一緒に変化していくことでチームになる
    • 文化に気を払っていないと新規メンバーが持ってきた文化がチームの文化になる
    • それはいい文化の可能性もあるが、そうじゃない可能性は高く危ない
    • チームが大切にしている文化を守ることが重要
  • チームの文化は、いいコードを重視する文化があればいいコードを重視する人が集まる、他人を攻撃する文化があるチームには他人を攻撃する人が集まる
  • 安全にアイデアを共有できる文化
  • 意志決定プロセスに口を挟める文化
  • 建設的な批判は難しい

    • それができる友達や同僚を見つけたら貴重な存在なので手放さないようにしておきたい
  • 同期コミュニケーションの人数を減らして非同期コミュニケーションの人数を増やす
  • チームのミッションステートメントを設定する
  • コードにはコミュニケーションが必要
  • リーダーシップについて

    • 尊敬を失う、という表現がしっくりきた
    • 今まで時にオイルになり潤滑に、時に糊になりくっつける、ということを意識してきたが、触媒になるという表現がしっくりきた
  • 人が有害なのではなく振る舞いが有害であると考える
  • 完璧主義を回避する
  • 優れたソフトウェアを書くことが仕事であって、訪問者の機嫌をとったり、自分のやってきたことを正当化したりすることではない
  • 争いごとは選ぶ
  • 短期的なメリットのために HRT の文化を妥協しない
  • 年に 1 回でも失敗しないようなら、それはリスクをとっていないのである
  • 組織の悪い習慣をやめるにはいい習慣と置き換える必要がある
  • ソフトウェアの第一印象をよくする
  • ユーザーのことを考える
  • 速度は機能
チャットツールは Slack で分報、 Twist で相談、という二刀流が最強の構成じゃないかと想像してる

前に書いたこの記事 チャットはコンテキストを適切に分けることが大事、分報とリアクションの組み合わせで心理的安全性の構築に役立てる | 5000164 is here では具体的なツールの話はしなかった。
ここでは具体的なツールとその使い分けについて想像していることを書く。

使うことを想定しているツール

下記の 2 つのツールの組み合わせがいいのではと考えている。
各ツールの特徴と使い分ける理由については後述する。

Slack のメリット

  • 全体的に使いやすい
  • カスタム絵文字として好きな絵文字を登録できる
  • カスタム絵文字でリアクションできるのがいい
  • リアクションが Activity で簡単に見れるのがいい

Slack デメリット

  • コンテキストが区切りやすいわけではない

    • 会話が簡単に混ざってしまう
    • 話題ごとにいちいちチャンネルを作るのが手間
    • チャンネルを作るたびに誰をチャンネルに追加すればいいのか考えるのが手間
    • スレッドが使いにくい

Slack から感じる思想

  • 書くコストを下げる (その代わり読むコストは上がる)
  • リアルタイム性を重視している

    • オフィスをオンラインに持っていくイメージ

Twist のメリット

  • ワークスペース > チャンネル > スレッド > 内容 という構造

    • Slack は ワークスペース > チャンネル > 内容 > 場合によってスレッド という構造

Twist のデメリット

  • リアクションに付けられる絵文字が少ない
  • カスタム絵文字が登録できない

Twist から感じる思想

  • 読むコストを下げる (その代わり書くコストは上がる)
  • 効率的なコミュニケーションを重視している

    • リアルタイム性をなくしてチャットに張り付く必要をなくそうとしている気がする

Slack と Twist を使い分ける理由

前に書いた記事の通り、チャットはコンテキストを適切に分けることが大事であり、分報とリアクションの組み合わせで心理的安全性の構築に役立つと考えている。
使い分ける最大の理由はここにあり、

  • Slack は分報と相性がいい
  • Twist はコンテキストが区切りやすい

からである。

Slack は書くコストをできるだけ下げることができる。
そしてカスタム絵文字とリアクションと Activity の組み合わせによって心理的安全性を構築していけると考えている。
しかし書くコストが下がっていく影響として、整理されていない文章が増え、コンテキストは混ざりやすくなり、どんどん読みづらくなっていく。

それに対して Twist ではスレッドという概念がある。
なにかを話すということは、その「なにか」という主題があるということになる。
その「なにか」ごとに会話を区切ることができればコンテキストは混ざらなくなる。
Twist では話したい内容ごとに新たにスレッドを立てて会話をするので、コンテキストが区切りやすくなる。

Slack では質問ごとに毎回チャンネルを作るのは手間だし、すでに存在する質問チャンネルがあればそこで質問してしまう。
Twist では Slack のようには分報は書きづらく、リアクションもしづらい。
そこでツールを統一する必要はないんじゃないか?と考え、 Slack では分報、 Twist では相談、と使い分けるのがよさそうだと想像している。

まとめ

  • Slack で分報、 Twist で相談、という二刀流が最強の構成じゃないかと想像してる
Apple Music で BGM にいい感じのプレイリストを作る
  • Apple Music には毎週自動で内容が更新される Chill Mix というプレイリストがある
  • For You から Chill Mix をライブラリに追加する

    • 追加しといた方がアクセスしやすくなって楽になる
  • 新規でプレイリストを 2 つ作る

    • 曲を溜めていく用のプレイリスト (例: Chill) と、一時的に保管する用のプレイリスト (例: Chill temp) を作る
  • Chill Mix の内容が更新されたら全曲を Chill temp に追加する

    • Chill Mix のプレイリストは編集できないので、気に入らない曲を外すために自分で編集できる Chill temp に入れる
    • Chill Mix をあんまり聞く時間がなかった場合もとりあえず Chill temp に退避しておけば Chill Mix が自動更新されても聞き漏らさない
  • Chill temp を聞いて、気に入らない曲があったらプレイリストから削除する
  • Chill temp をしばらく聞いて、いい感じだったら Chill temp の全曲を Chill に追加して Chill temp を空にする
  • これを繰り返すことでいい感じの曲だけが Chill に溜まっていき、 BGM にいい感じのプレイリストが出来上がる
メンションの通知を全員切るべき、という仮説

メンションの問題点は通知が飛ぶこと

メンションの問題点は「通知が飛ぶこと」ということに尽きる。
通知というのは注意を引いて作業を中断させるものなので、緊急度が高い場合以外には作業の邪魔となる。
しかし「誰に対して発言しているか」という情報は大切である。
でもメンション機能を使用せずに「○○ さん」という書き方をすると見逃しやすくなってしまう。

ソフトメンションとハードメンションという概念

そこで自分はソフトメンションとハードメンションという概念を考えた。
ソフトメンションは、通知が飛ばないメンションである。
ハードメンションは、通知が飛ぶメンションである。
基本的にソフトメンションを使用することで、相手の邪魔をせずに意図を明確にしながら会話が行えるようになると考えられる。

対応しているチャットツールがない

しかし現時点で自分が知る限りではソフトメンションとハードメンションという概念を導入しているチャットツールはない。
簡単にスヌーズ機能を設定できるようにはなっているが、毎回手で設定するのは手間である。

そこで、メンションの通知を全員切るべき、という仮説

大事な点は、自分が通知を切っているという点ではなく、相手が通知を切っているという点である。
相手に通知が飛ばないとわかっているからこそ、相手の邪魔になることを心配せずにメンションを飛ばすことができるようになる。
なので、チーム全体のルールとする必要がある。

運用する際の具体的なルール案

  • 全員メンションの通知を切る
  • チャットを見るタイミングや頻度を個人個人でそれぞれ決める

    • 始業時、昼休憩後、終業前、など
    • 人によってチャットを使用する量が異なるので一律なルールは難しい
  • 緊急度の高い呼び出しが必要となることが想定されるなら他のツールで通知が飛ぶようにしておく

    • 電話とか LINE とか

よりわかりやすいコミュニケーションを目指して

メンションは「発言を誰に向けているのか」を表現するためのものであり、現実世界で言うと向いている方向や目線に相当し、通知を飛ばすためのものではないと考えている。
通知を飛ばさないようにすることで、よりわかりやすくコミュニケーションできるのではと予想している。

設定ファイルを Scala で書く

背景

  • リポジトリに入れたくない情報は別ファイルに設定として書く
  • 型が表現できないのが面倒くさい

目的

  • Scala で設定ファイルを書けるようにする

やり方

  • Scala で設定を書いて Eval する

ディレクトリ構成

  • resources 以下に設定ファイルを入れてしまうと生成された jar に含まれてしまうのでトップディレクトリに設定ファイルを配置する
.
├── build.sbt
├── Settings.settings
├── SettingsSample.settings
└── src
    └── main
        └── scala
            ├── infrastructure
            │   └── Settings.scala
            └── interfaces
                └── Application.scala

具体的なコード

依存関係を解決

  • build.sbt
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value

設定を Eval する

  • infrastructure/Settings.scala で設定を表現する
  • System.getProperty("settings") を使うことで使用する設定ファイルを実行時に指定できるようになる

    • 例: java -Dsettings=Settings.settings -jar run.jar
package infrastructure

import scala.io.Source
import scala.reflect.runtime.{currentMirror, universe}
import scala.tools.reflect.ToolBox

object Settings {
  val toolbox: ToolBox[universe.type] = currentMirror.mkToolBox()
  val settings: SettingsType = toolbox.eval(toolbox.parse(Source.fromFile(System.getProperty("settings")).mkString)).asInstanceOf[SettingsType]
}

trait SettingsType {
  val hoge: String
  val foo: Int
}

設定を書く

  • Settings.settings

    • 拡張子が .scala だとコンパイルされてしまうのでコンパイルされないように拡張子を任意の拡張子に変える

      • IntelliJ でこの拡張子を Scala ファイルとして開くという設定をすることでコードを補完しながら設定を書くことができる
import infrastructure.SettingsType

new SettingsType {
    override val hoge = "hogehoge"
    override val foo = 1
}

設定のサンプルを書く

  • 設定方法がわかりやすいようにサンプルを SettingsSample.settings として作っておいてリポジトリに含める
import infrastructure.SettingsType

new SettingsType {
    override val hoge = ""
    override val foo = 0
}

設定がリポジトリに含まれないようにする

.gitignore

Settings.scala

使い方

  • interfaces/Application.scala
package interfaces

import infrastructure.Settings.settings

object Application extends App {
  println(settings.hoge)
  println(settings.foo)
}

参考

Scala でコマンドライン引数を分解する

下記のように書くことでコマンドライン引数を分解できる。

val keyArgs = args.collect {
  case "--dry-run" => "dry-run"
}.toSet
val keyValueArgs = args.sliding(2).toList.collect {
  case Array("--date", specifiedDate: String) => "date" -> Some(specifiedDate)
}.toMap
--date "2018-05-15 00:00:00" --dry-run

のようなコマンドライン引数を渡した時に keyArgskeyValueArgs はそれぞれ下記のようになる。

// keyArgs
Set("dry-run")

// keyValueArgs
Map("date" -> Some("2018-05-15 00:00:00"))
チャットはコンテキストを適切に分けることが大事、分報とリアクションの組み合わせで心理的安全性の構築に役立てる

最近チャットのことをよく考えている。
ある程度の認識が自分の中で固まってきたのでここで一旦まとめる。

前提

チャットは難しい。
チャットをうまくしたらすべてが解決するとは思ってなくて、少しでも現状を良くするためのツールとして使う。

チャットのいいところは

  • 読み返すことができる
  • 検索することができる
  • 多くの人が読むことができる
  • 非同期でコミュニケーションができる

というところ。

この記事では書いていないこと 2018.5.27 追記

  • 具体的なツールの比較
  • コンテキストを分ける時にかかるコスト

チャットで重要なのはコンテキスト

チャットは文字に残ることで複数の人が非同期的にコミュニケーションをとることができるというメリットがある。
このメリットを有効的に使うためにはコンテキストを適切に分ける必要がある。
コンテキストはチャンネル、スレッド、ルームなどで分ける。
コンテキストを適切に分けることで情報のやりとりがスムーズになる。

チャットの種類

一口にチャットと言ってもすべてのチャットを同じように扱えばいいわけではない。
実際の会話に雑談や会議といった種類があるようにチャットにも種類がある。
雑談のようなチャットでは気軽に書き込むことができるし、会議のようなチャットでは書き込むのに慎重になる。
チャットの種類は発言する場所がどのようなコンテキストを持っているのかによって決まる。

チャットのコンテキストが混ざるとコストが増加していく

チャットはコンテキストが混ざると書くコストも読むコストも増加する。
チャットは 1 つのチャンネル、スレッド、ルームの中で発言が時系列にしたがって流れていく構造になっている。
この 1 つの流れの中に 2 つ以上の話題があったらそれはコンテキストが混ざっている状態と言える。
チャンネル、スレッド、ルームで話されている内容に見合わないほど多くの人が参加している状態もコンテキストが混ざっている状態と言える。

適切なコンテキストがないと発言しづらくなる

例えば A さんが下記のようなチャンネルに参加していたとする。

  • 全社チャット (参加人数 50 人)
  • チームチャット (参加人数 10 人)
  • B さんとのダイレクトチャット (参加人数 2 人)

A さんが No. 1 のイシューについて B さんに聞こうとした時にどのチャンネルで聞くのが適切だろうか。
チームチャットでは別の話題が話されており、流れを遮って聞くのはチャンネルの参加者全員にチャットを読むコストが増加する負担をかけてしまう。
しかし全社チャットではそれ以上にいろんな話題が話されており、参加している人数も多い。
ダイレクトチャットで聞いたら他の人への負担はかからないが、質問内容を他の人も知りたかった場合などに知識が資産として蓄積していかない。
上記のような状況だと適切なコンテキストが見つからず発言がしづらくなり、知識の共有が滞ってしまうなどの問題が起きることが考えられる。

この時

  • No. 1 のイシューについて話すチャット (参加人数 5 人)

というような、 No. 1 のイシューについてのみ会話しており、参加している人も関係者だけ、というようなチャットがあれば発言するコストが下がり、スムーズに知識が共有できると考えられる。

コンテキストが混ざっていると読みづらくなる

あるチャンネルで下記のようなやりとりが行われていたとする。

A さん: B さんに No. 1 のイシューについて質問
C さん: D さんに No. 2 のイシューについて質問
B さん: No. 1 のイシューについて回答
E さん: B さんに No. 3 のイシューについて質問
A さん: B さんに No. 1 のイシューについてさらに質問
F さん: 作業内容のちょっとしたつぶやき
B さん: No. 3 のイシューについて回答
A さん: No. 1 のイシューについての質問に追記
D さん: No. 2 のイシューについて回答

このようにコンテキストが混ざっている状態だと、読みながら脳内で話をつなぎ合わせたりする必要があり、読むのにとてもコストがかかる。
このやりとりを 1 つのチャンネルではなく、下記ようなチャンネルに分けてやりとりをしていたとする。

  • No. 1 のイシューについて話すチャット (参加人数 5 人)
  • No. 2 のイシューについて話すチャット (参加人数 3 人)
  • No. 3 のイシューについて話すチャット (参加人数 10 人)
  • 各個人用のチャット (参加人数 10 人)

このように適切なコンテキストに区切ると下記のようなやりとりになる

  • No. 1 のイシューについて話すチャット (参加人数 5 人)
A さん: B さんに No. 1 のイシューについて質問
B さん: No. 1 のイシューについて回答
A さん: B さんに No. 1 のイシューについてさらに質問
A さん: No. 1 のイシューについての質問に追記
  • No. 2 のイシューについて話すチャット (参加人数 3 人)
C さん: D さんに No. 2 のイシューについて質問
D さん: No. 2 のイシューについて回答
  • No. 3 のイシューについて話すチャット (参加人数 10 人)
E さん: B さんに No. 3 のイシューについて質問
B さん: No. 3 のイシューについて回答
  • F さん個人用のチャット (参加人数 10 人)
F さん: 作業内容のちょっとしたつぶやき

発言されている数に変わりはないが、このように非常に読みやすくなり、読むコストを軽減することができる。
さらに、自分に関係のあるチャット、関係のないチャットを細かく制御することができるので、不要なチャンネルには参加しないことで読むチャットの絶対量を減らすことができる。

コンテキストを適切に分けることが大事

コンテキストを適切に分けることで書くコストも読むコストも減らすことができる。
チャットの種類に応じて相性のいい形でコンテキストを分けていく。
多くの発言を促すためには狭い話題で少ない人数で区切り、書くコストを下げて発言をしやすくする。
多くの人で共有しておいた方がいい内容を話す場合は多い人数で区切り、書くコストを上げてしっかり推敲された文章だけが流れるようにして全体にかかる読むコストを下げるようにする。

情報の透明性とチャット

情報の透明性とはすべての情報を公開することではない。
情報の透明性とは、ある決定事項とそこに至る経緯を正しく共有すること。
情報の透明性が高いことによって情報の格差がなくなり、個人個人が合理的な判断を取れる可能性が高まる。
大事なことは決定事項とその経緯の共有であり、全員がすべてのチャットを読む必要はない。

心理的安全性とチャット

心理的安全性とは、自分が自分のままでいることができる雰囲気のことである。
心理的安全性が構築できていないと、発言することが恐怖になりチャットが機能しなくなる。
心理的安全性を構築することはとても重要である。

分報が心理的安全性の構築に役立つのではないかという仮説

分報とは下記のようなものである。

分報を経験して「自分の部屋を持つ」ということがとても価値のあることだと感じた。
特定のコンテキストで区切られたチャンネルで発言する時は、発言の先に必ず誰かが存在する。
質問であったり、回答であったり、情報共有であったり、誰かに向けて発言するものである。
しかしこれが自分の部屋というものを持つことによって、誰にも向けていない発言をすることができるようになる。
自分の部屋で自分が自分のまま発言することができる。
これによって少しずつ自分を開示していくことができ、わからないことをわからないと言えるようになるなど、心理的安全性の構築に役立つのではないかと考えている。

リアクションの重要性

発言に対するリアクションは下記の 2 点で重要である。

  • チャットの流れを阻害しない
  • 発言に対する反応を計測できる

リアクションはチャットの流れを阻害しない

リアクションは局所的にコンテキストの支流を作ることができる。
例えば誰かの発言に感謝したい場合に、全員がありがとうございますと返信すると下記のようにチャットが読みづらくなってしまう。

A さん: ○○ をリリースしました
B さん: ありがとうございます
C さん: ありがとうございます
D さん: ありがとうございます
E さん: □□ の件は問題なかったでしょうか?
F さん: ありがとうございます
G さん: ありがとうございます

こうなってしまうとチャットに参加している人の読むコストが増加してしまう。
さらに気付くまでに時間がかかった場合はすでに他の話題になっている場合があり、特定の発言を直接指定しないとどの発言についてなのかがわからなくなっているので、さらにコンテキストが混ざって読みづらくなってしまう。
しかし発言していないからといって感謝していないというわけではない。
そのような時にリアクションをすることによって、特定の発言に対して局所的にコンテキストの支流を作って本流の流れを阻害せずに感謝などの意思を伝えることができる。

リアクションは発言に対する反応を計測できる

  • リアクションを使うことでチャットの流れを阻害せずに反応することができる
  • リアクションは手軽に行うことができる

これらの要因によってリアクションを行う敷居が低くなる。
敷居が低くなった結果として、リアクションがよく行われるようになる。
リアクションがよく行われるようになると、発言に対する反応を計測できるようになる。
この、発言に対する反応の計測は、心理的安全性の構築に役立つと考えられる。
例えばチャットで質問した時に、その質問にいいねのリアクションがついたりすると、聞いてよかったんだと実感できて不安が軽減されるなどの効果がある。
カスタム絵文字を使うとより適切な絵文字を選ぶことができるようになり、さらに具体的に反応を計測できるようになる。

分報とリアクションは相性がいい

分報で心理的安全性を構築する際に、さらに効果的にするものがリアクションである。
分報によって自己を開示しても、フィードバックを得られなければ心理的安全性は構築できない。
リアクションによって、発言よりも簡単にフィードバックを得ることができる。
分報で自己開示した発言にリアクションがつくことによって、受け入れられることを観測することができ、自分は自分のままでいていいんだと実感して、心理的安全性が構築されていく。

まとめ

  • チャットはコンテキストを適切に分けることが大事
  • 分報とリアクションの組み合わせで心理的安全性の構築に役立てる

参考

Scala から Java ライブラリを使った時のメモ

build.sbt でライブラリの追加

libraryDependencies += groupID % artifactID % revision

のように書く。
最初 Scala の略記法のように %% と書いていたのでうまく動かなかった。

型のキャスト

Java ライブラリに渡したりするためにキャストする時は asInstanceOf を使う。
また、

import collection.JavaConverters._

のようにインポートしておくことで asScalaasJava でコレクションを変換できる。

null を Option に変換

Java ライブラリのメソッドが null を返す場合がある時に、 Option(func(value)) のように Option を使うことで Option 型に変換できる。
値があったら Some(result) が返ってきて、 null だったら None が返ってくるようになる。

行動を変えるのは否定ではなく前進である

ふと思ったこと。
自分の行動を変えるということに抵抗があるのは、今まで行動してきたことが否定されるような気がするからなんじゃないかと思った。
変化にはコストがかかるから、とかそういう話とは別にして。

否定だと感じてしまう理由

限られた情報の中で選択し続けないといけない。
だから選択を間違えることはよくある。
A と B を比較して、 A を選んだとして、後からやっぱり B がよかったと B に変えたとする。
そうすると、 A を選んでいた期間が間違いだったように感じてしまう。
その期間を否定されたと感じてしまうのではないかと考えた。

行動を変えるのは否定ではなく前進である

A を選ぶことで人生に 10 のいいことがあるとして、 B を選ぶことで人生に 15 のいいことがあるとする。
もちろん最初から B を選べることが理想だが、人間は間違えるので、 A を選ぶことだってよくある。
A を選んだ後に B に変えると、 A を選んでいた期間がもったいないと感じてしまう。
後から「実は A の方がよかった!」となることを期待してしまう。
だがこれらはサンクコストであり、囚われてはいけないものだ。
人間に出来ることはその時々で最善の選択をし続けることであり、過去にいくら間違っていようと A から B に変えることでいいことが増えるなら変えるべきである。
A を選んでいた期間は間違っていた期間ではなく、その時に行った最善の選択の副作用でしかない。
行動を変えるということは、過去を否定して正しい方向に持っていくことではなく、もう一度最善の選択を行い、一歩前に進むということである。

過去の選択も尊重して受け入れていく

過去の選択もその時点では最善の選択を下したはずである。
そのことを尊重して受け入れていく。
自分は頑張って前に進んでいるんだということを認める。
あらゆることがどんどん変わっていくことを受け入れる。
過去の選択は改善して未来の選択に取り入れる。
行動を変えるということは、過去を否定することではなく、また一歩前進するということである。

Basic 認証の realm は正しく設定する

sbt で Basic 認証がかかっている依存を解決するために ~/.sbt/.credentials に認証情報を書いていたけど、 realm がずれていたせいで認証に失敗するということが起きた。
realm とは領域という意味で、おそらく ~/.sbt/.credentials の host と realm からどの認証情報を使用するのか判断している気がする。
なので、 realm がずれていると認証に失敗する。

正しい realm は curl で確認できる。

curl -v <対象の URL> 2>&1 | grep realm