bussorenre Laboratory

hoge piyo foo bar

コンテキストスイッチに立ち向かう - 複数案件を抱える中で生産性を高めるために

この記事はRecruit Engineers Advent Calendar 2018 の1日目の記事です。
2日目は→ Go言語を使って一年間が経った

こんばんは。 @bussorenre です。初日からアドベントカレンダー脱稿なんて事にならずにホッとしています。(大汗

この記事は半年ほど前に書いた コンテキストスイッチにどうやって立ち向かうか の続編になります。自分なりにあれこれ最適解を見つけてきたので共有します。

コンテキストスイッチとはなにか?

コンテキストスイッチとは、元々はCPUのマルチタスク処理のために考案された仕組みの事で、複数のプロセスが1つのCPUを共有できるように、CPUの状態(コンテキストと呼びます)をメモリ等に退避させたり、退避させた情報を元にCPUの状態を復元したりを切り替えながら、あたかも複数の処理を並列に実行しているかのように見せる処理の事を示します。

この記事はCPUのコンテキストスイッチングに関する解説ではないので詳細は wikipedia とか コンテキストスイッチの仕組み - 日本OSS推進フォーラム などを参考にしてください。

この記事において「コンテキストスイッチ」と呼ぶのは、 人間が行っている作業を何らかの要因により中断させ、別の作業に切り替えること を示します。また、切り替えの際に生じる作業を中断しなければ発生しなかったであろう余計な作業 の事を「コンテキストスイッチコスト」と呼びます。

エンジニアにおけるコンテキストスイッチ問題

基本的に、エンジニアリング業務は非常に大きな集中力を求められます。 新しい機能の設計や不具合の原因調査等には、熟考が求められることが多く、途中で全く関係の無い話題を振られたりすると、「あれ?オレ今どこまで何を考えていたっけ?」となりがちです。

すると、先程の思考を取り戻すのにメモをみたり、コードを見直したり、仕様書を読み直したりしますし、最悪の場合、先程の思考は帰ってこないかもしれません。

私の話

実際の業務中にあった話ですが、4月から6月くらいまで、私は4つの業務を並行して担当していました。具体的には以下の4つです。

  • サービスAの新規機能開発
  • サービスAの営業行動の最適化
  • サービスBの定常保守
  • オフィスの引越(Wi-fi等のオフィスインフラの要件定義と発注とか)

この中で、最も重要な仕事は、「サービスAの新規機能開発」だったのですが、引っ越しは日程が差し迫ってて緊急度が高く、営業は物理的に声が大きいのでよく割り込みタスクを持ってくる。突然サービスBの案件が降ってくる等、コンテキストが目まぐるしく動いている状態でした。

結果、最も重要な「サービスAの新規機能開発」が滞る。という事態が発生しました。

世の中にはコンテキストスイッチ耐性が高い人というのが一定数居て、どんな状況からでも瞬時に頭を切り替えれる素晴らしい脳を持った人が居るのですが、残念ながら私の脳はシングルコアなので、コンテキストスイ ッチ耐性が低いです。

あまりにもスイッチが発生すると、自分が何を考えているのかわからなくなって混乱し、業務に手が付かない。整理にすごく時間がかかることがあります。

コンテキストスイッチはいつでもどこでも発生する

オフィスの引越終わったし。サービスBの案件が降って着やすい時期も抜けたし、「サービスCの新規機能開発」に業務を絞る調整を上長にしてもらい、このときは解決しました。 (ちなみに、どこからCが湧いてきたんだっていう話はココでは一旦ツッコまないでくれ……)

しかし、9月頃から、再び私の集中を妨げる事態が発生し始めました。

具体的には以下の要素です。

  • 新規大型開発案件が始まる
    • どうしても、認識のすり合わせや仕様/設計/スケジュールの調整等で会議・会話が増えてしまう
  • 突然のCS対応。
  • クライアントに訪問して調査しなければならない案件の設計・実施
  • (プライベート要因ですが)引っ越し
    • 急遽決まった。その調整とか準備とかで、昼間にガス会社から開栓手続きの電話が来るとかがあった。
  • 同僚の雑談が普通に面白い
    • ついつい雑談に乗ってしまう

期の変わり目・繁忙期等はどうしてもコンテキストスイッチが発生しがちです。また、私はまだ独り身ですが、今後、結婚するとか、子供が生まれるとかがあるかもしれないし、親の介護とかが発生したりすることを考えると、コンテキストスイッチが発生しないことはありえません。むしろ増えそう。

そこで、真剣にコンテキストスイッチ問題に立ち向かうことにしました。

コンテキストスイッチの発生源を特定する。

まずは、原因分析から始めます。 原因分析には、 Jins MEME の力を借りました。

f:id:bussorenre:20181201143904p:plain
Jins MEME ES

一週間ほど、この眼鏡を掛けて業務を行い、「集中力が続いている日」と「集中力が断続的になっている日」をピックアップします。

f:id:bussorenre:20181201143655p:plain
jins MEME による計測結果

それぞれピックアップ出来たら、ユーザーストーリーマップの要領で、一日の自分の行動を詳細に可視化します。
可視化する際には、github のコミットログ、Slack のチャット履歴、メールの送受信履歴 などを参考にします。

これらを元に、コンテキストスイッチへの対処を考えます。

私の場合、大きく5つの要因があることがわかりました。

  • Slack の投稿/閲覧 頻度
    • 最もコンテキストスイッチを生んでいる媒体
    • 文字でレスポンスする頻度は低いが、わりとポンポン :yosasou: みたいなリアクションを取っていることが多い。
    • 頻繁にリアクションしているということはしょっちゅう Slack にコンテキストスイッチさせられてる可能性が高い
  • メール
    • しれっと重要なメールが飛んでくることがあるので、読まないわけには行かない。
    • しかし中には、どうでもいい広告とか、通知系のメールも多い。
  • 会議
    • 基本的に多い。
    • デイリースクラム等の些細なものから、部定例等参加者の大きいものまで、結構ウェイトが大きい。
  • 相談、雑談等
  • 並行業務
    • 午前中Aをやっていて、突然Bを対応してくれ的なのが発生した。等

これらに対し、それぞれ対策を実行していきます。

コンテキストスイッチの発生頻度を下げる

Slack

私は一見でも未読があるとすごい気になってしまうタイプなので、ちょっとでも光ったらすぐSlack を見に行く癖があります。

基本的に、以下の方針で、見なくていい情報を徹底的に排除する方針で動きました。

  • 重要なチャンネルは★をつける
    • development 等の、メンションが無くても読むべきチャンネルは★に入れます。
  • 重要じゃないチャンネルは見ない。
    • general/random チャンネル等
    • 基本的に @channel@here がつかない限り見に行きません。
    • 後から(通勤時)とかに纏めて読みます。
  • 見なくていいチャンネルは /mute してしまって見ない
    • じゃぁ /leave すればええやんってなるかもだけど、大事なときには通知を飛ばしてほしいときに使う
    • alert や notifications チャンネル的なので有効

この方法により、slack を読む頻度はかなり下がってる気がします。

何度も聞かれる質問はBOTで答えれるようにする。

オフィスの無線LAN などを管理している関係上、中途入社の方や異動で来た新任の方に、質問をされるケースが何度かあります。 社内のルールなど、答えが決まりきっているものは、BOT に聴いたら応答できるように整えます。

f:id:bussorenre:20181201152834p:plain
Dialog UI を使ってよくある質問を自動で返すようにしている。

メール

やることは非常にシンプルで、

  • フィルターでフォルダ分けをして、見なくていいメールは全部別フォルダに入れます。
  • わけわからん広告は全部配信設定をオフに。
  • オフに出来ないやつは迷惑メールにぶっこむ

の3つだけです。これだけで、読むべきメールしか残らないので、かなり生産性が上がります。

物理的な逃げ場所を作る

強い集中を求めたい場合は、他人の声が入りにくい場所に移動して仕事をします。 多くの人はカフェとかコワーキングスペースとか、サテライトオフィスとかがそれに相当するのかな……? リモートワークが100%許可されているからこそ可能な芸当。

私の場合はサーバールームが、良い隠れ家になってます。

エンジニアでもあまり入ってこようとは思わない空間で、まず人が来ることはありません。
社内のサーバールームはオフィスインフラのトラフィックをさばく機械しかないので、問題はありません。

ファンの音しか聞こえない空間にかなり癒やされる。

1 on 1 を上手く使う

現在は上長との 1 on 1 が隔週に一回あるので、その場で、今自分が何をやっているか(公私共に)、何を感じているかを可能な限り伝えます。 具体的な方法については。もうちょっとうまいやり方を模索しているんですが、自分が何をやってるかを公私共に伝えるという方向性は有効だと感じてます。

会議のリモート化

基本的に、スプリントレビュー等の大事な会議以外は、可能な限りリモート参加OKにし、発言が求めらてたタイミングだけ発言する等をします。 たとえオフィス内に居たとしても、30分の会議に常時コミットする必要はなく、自分が関わる部分だけをピックアップして参加し時間を作ることが出来ます。

コンテキストスイッチが発生したときのスイッチングコストを最小限にする

コレまでは、コンテキストスイッチが発生しないようにする工夫でしたが、ここからは、コンテキストスイッチが発生した時のコストを最小限に収める努力を紹介します。

scrapbox に逐一メモを書きながら作業する

作業メモなどを逐一残して、後から引し出しやすいようにします。

かつては、Sublime Text (後にvisual studio codeに変更)のような、不意のQmd + Q にも耐えられるバッファを使っていたのですが、最近 scrapbox が有効だと感じています。

何を考えていたか後から引っ張りやすいので、一時的なメモ置き場として最適なだけでなく、中途半端なアウトプットを纏めておく事で、後から練度の高いアウトプットに昇華させやすくなる(ブログへの投稿等)と思ってます。

チームで使用しているscrapbox, 個人で使っている公開scrapbox, 個人で使っている非公開scrapbox の3箱を並行して運用しています。

Scrapbox についてはまた別で記事書きます。

タスク / チケットを可能な限り分解し、誰からも見えるようにする

チーム開発において、誰が何を担当しているかの可視化(JIRAでチケットを明確に切るなど)チケットのスコープの明確化、当然のごとく行います。

「あ、そのチケット終わってます」みたいな会話をしょっちゅうPMとするのはコミュニケーションの無駄なので、意識してJIRAのチケットの状態を最新に保つようにします。

また、JIRAとは別に、個人のTrello ボード を持っています。

f:id:bussorenre:20181201152614p:plain
自分のTrello

複数の案件を持っていたり、複数チームにまたがって仕事をしているときに有効で、基本的にチーム内の人が見れる場所においておき、「こいつ今何やってるんだ…?」というのがひと目で分かるようにラベリングしています。「Aという案件で忙しいのにBという重い案件が急に降ってきた!ギャー」という事を防ぎやすくなります

これらの努力により、「聞くな、ココに書いてある、見ろ」というコミュニケーションが成立するので、作業を中断するような会話が発生しにくくなります。

タスク管理は特に発生しやすいので特筆しましたが、基本的にチーム人数が増えれば増えるほど、ドキュメント化は正義だと思っており、上手くドキュメント化をすればするほど、コンテキストスイッチコストが下がると思ってます。

コード上に大量にメモを残す

コミットしてプルリクエストになるときには消えているんだけど、作業中には残しておくと便利なコメントをとにかく書き残します。 仕様が固まっていなかったり、自分が知らない実装に挑戦するときなどは非常に有効です。

また、コードレビュー中も、github 上でザクッとPRのコードを見るのではなく、 ローカルに落としてきて、ローカルブランチ上で大量にメモコメントを書きながら見るようにします。

ローカルで feature/hogehoge_review みたいなレビュー専用ブランチを切って残して置くと、 後々見返したいときに参照できて便利です。

メールの定型文を大量にIME に登録する

社外の人や、グループ内の別企業の方とのやり取りといったことが割とあるので、とにかくメールにかける時間を短縮します。

最もシンプルで効果があるのは、定型文をIMEに登録することです。

変換前 変換後 備考
th 大変お世話になっております。
rmpm リクルートマーケティングパートナーズ 松本です 相手によって肩書を変えたい場合など他の短縮語がある
gm ご迷惑をおかけし、大変申し訳ありません。 謝罪メール多いな…
おt お手数をおかけしますが、何卒宜しくお願い致します。 お疲れ様です。と勘違いしやすい

これだけでメールの返事に書ける時間が相当短縮できます。

試したけどあまりうまく行かなかったこと

do not disturb を使う

Slack には do not disturb という、一定の時間の間一切の通知をオフにする機能が存在します。

f:id:bussorenre:20181201154337p:plain
do not disturb

コンテキストスイッチを発生させないという意味では非常に有効だったのですが、重要な連絡(本番環境でエラーが頻発している等、コンテキストスイッチさせてでも対応しなきゃならない事)を逃して対応が遅れるという事があったので、やめました。

リモートワーク環境を超絶整える

f:id:bussorenre:20181201144005p:plain
bussorenre のリモートワーク環境2018

「突然話しかけられて、あれこれ対処しなきゃならない」。みたいなケースはダントツで減るのですが、オフィスに居ないコミュニケーションロスをSlack で補うことになり、結果としてSlack を見ていないと気が落ち着かない。という状態になりました。

ただ、あくまで「コンテキストスイッチに立ち向かう」という意味であんまり効果がなかっただけで、リモートワーク自体は非常に生産性を上げるのに有効です。

「ちょっと今日調子が悪いけど、休む程ではない」ときにリモートワークを活用すると、通勤コストを支払わない分、体力的に非常に効果的だったりします。

また、明らかにやることが明確な時などにリモートワークを実行すると、まとまった時間が取れるのでかなり捗ります。

Jins MEME で定常的に自分の状態を監視する

最初の課題設定フェーズにおいては非常に役に立ってくれたのですが、常用するには、「額の違和感により集中力が下がる」という壁を超えることが出来ませんでした。

端的に申し上げると、つけ心地が悪く気持ち悪い。というのが慣れだけでは解消できませんでした…。

Jins MEME 3くらいで改良してくれることを期待。

副業を止める

あまりにも目まぐるしくて参っていたときに取った手段です。効果は何よりも絶大だったのですが、デメリットが大きすぎました。具体的には、「収入が下がる」 「社外でのアウトプット機会が減る」の2つです。

しかし、当時を振り返って改めて冷静に考えると、「こんなに厳しいコンテキストスイッチングに晒されたら転職すればよくね?」と思ったので、次回厳しい環境に身をおくことになったら転職活動という手法を試すのが良いのかも? :thinking_face:

最後に

みんな当たり前にやってることばっかりの事を紹介しただけの記事になったかもしれませんが、まぁ個人の試行錯誤の結果ということで記事にしました。

また、これらの思考錯誤を行う上で、 エンジニアの知的生産術 - 効率的に学び、整理し、アウトプットする が非常に助けになりました。いい本です。おすすめです。

「こういうツールあるよ」とか「こういう方法を取っている」等のご意見コメントや、「お前そこ全然出来てへんやん」みたいな、耳の痛い話がありましたらぜひ頂けると嬉しいです。

ご精読ありがとうございました。