SCRUM FEST Osaka 2022 に参加しました!イベントレポート2

メガネひげ面、のび太型サブマネージャーの、富田と山本が「SCRUM FEST Osaka 2022」に行ってきたよ!

ほう、なんとこなれたオン・オフハイブリッド型カンファレンス! ちょっとまて、これって会場に来る必要あったのか?(伏線)

印象に残ったセッション(山本版)

フルリモート下でのチームビルディング

推進するフルリモートの中で、カルチャーを大事にしながら、ポテンシャルが発揮できる場をどう醸成するのだろうか...最近はずっとそんなこと考えています。

参考 → Scrum Fest Osaka 2022 フルリモート下でのチームビルディング

チームメンバーを巻き込んでロードマップを作成・アップデートする

メンバー全員が現在地を認識し、目的地を共有しながらロードマップを調整する。そのことでオーナーシップが生まれそうだ。

組織作りと個人の成長の両方に役立つワークシップ

相互理解を深めるワークショップ、たとえば「バリューカード」や「スキルマップ」。

実は弊社でも「※オフサイトMTG記事」のアイスブレイクでバリューカードをプレイしてみました。 むちゃくちゃ盛り上がったし、メンバーの意外な一面を発見することができました。

うむ

チームという土台の上に「成果」を積み上げていく... チームビルディングとは、チームで最大の成果を出すための土台作りである

私たちの土台とはなんだろうか?

モブとソロを織り交ぜてハイアウトプットなチーム開発

ソロワーク、モブワーク...組み合わせて、良いとこ取りをしてアウトプット増大! 言うには容易いが、その運用の知恵には「ほうほう、なるほど」

参考 → モブとソロを織り交ぜてハイアウトプットなチーム開発

ソロワークとモブワーク

担当したタスクに単独で集中して成果を出していく「ソロワーク」しかやったことがない私は、モブプロやモブワークに実体験がなく、頭では目的やメリットを理解しつつも、うまくやる知恵が足らない。(やってみればいいんだけどね)

ソロワークとボブワークそれぞれに、向き不向きがあるって事。 そこで両方を織り交ぜたハイブリッドな運用で、フロー効率とリソース効率のバランスを取って行こうぜ、というアイデアに注目したい。

うむ

モブかソロ、どちらで取り組むかを最初に宣言することが大事(ソコがScrumらしさかと感じた)。 そして、モブで取り組んでいることが単純作業などのソロ向きに移行した時に、ソロに移行したことを宣言し、残りのリソースは別のタスクに着手する。ソロが完了したとき、モブに合流するという流れもある。

モブワークとソロワークは、柔軟に使い分ければよい でも、いま取り組んでいることがどっちなのかを共有しないと、デメリットが出てきてしまうだろう

面白いなぁ

実践!勝手に育つチームの作り方

自律したチームとなるには、どこまで権限があるのかを明確にしておく必要がある。 実際に「デリゲーションポーカー」を体験して、認識を合わせ、未来像まで描くことが出来た面白い体験

参考スライド

チームを強くする

必要なスキルに対して、チームメンバーの現状のスキルレベルを明らかにする。そこから、成長すべき方向や採用計画を明らかにする。

デリゲーションポーカー

権限を委譲するレベルを段階に分けて。マネージャーの期待値とメンバーの希望を話し合い、両社で決定する。 そして、将来はどういう状態が望ましいかを共有し、方向性を共有する。

うむ

意思決定のあり方について「責任と権限の委譲」の課題は、なかなか進捗しない、あるあるだ。

「デリゲーションポーカー」ってのを初めて知ったが、ワークショップで良い体験ができたことは、むっちゃ楽しかった。

権限移譲は Baseconnect でもよく話題になる課題。 それを明快に表現できる手法なので、ぜひやってみたい。

本編は懇親会にあり

会場に足を運んでみると、セッションの内容はオンライン... 確かに熱量やムードを感じ、パワーを受け取ることができるのだけど...

と、おもいきや、オマケと思っていた懇親会では、「濃い面々」の興味深い話が... 「スクラム、良さそうだからやってみたくて」なんて漏らそうもんなら、嵐の禅問答が!

勉強不足でしたぁ

Scrum とは何なのだ?

面白いことに、スクラムを知る人ほど、この問いで遠目になる。 それはどういう事象なんだろうと思案していると、散歩中にふとシナプスが繋がった。

私はデザインを学んだが、「デザインとは何ですか?」という問いに似ているんだろう。しかし未だに、デザインの本質を射抜く言葉は持ち合わせていない。そして、デザインを知れば、良いプロダクトが生み出せるというわけでもない。あえて、デザインは何かと言えば、それを探し続けるマインドそのものなのかもしれない。

チームメンバーの成長に期待するから、ScrumというKATAを学ぶのだ

Scrumは、近代的な開発手法、あるいはフレームワークだと思っていたが、実は、チーム自身が成長するための鍛錬でありKATA(型)なのである。

SCRUM FEST Osaka 2022に参加しました!イベントレポート1

6/17(金)、6/18(土)に開催された「SCRUM FEST Osaka 2022」に、サブマネージャーの山本と一緒に参加しました。

今回のscrumfesはオンラインがメイン、現地会場からの参加も可能なハイブリッド開催でした。

6/17(金)

この日は、16:30からオープニングトーク、17:00から角 征典さんの基調講演でした 私達は、 業務後に会社から鑑賞しました。

基調講演「クリーンスクラム―基本に立ち戻れ―」

感想

DS(どうかしている)というパワーワードは、しばらくアジャイル界隈で語られそう…

尖った人もいるチームはそれだけイノベーションが起こりやすく、そんなチームを取りまとめるのがスクラムマスターの役割の一つ。多様性大事。

スクラムの要素を新しい角度から一つ一つ分析していく内容は圧巻でした。

F1大阪グランプリ22

感想

基調講演と各コミュニティからの紹介セッションの後は、「F1大阪グランプリ」が開催されました。

「F」はフィードバック。とのことです。

各地で活躍しているアジャイルコーチの方々が、お題に対してフィードバックしていく「大喜利」的な内容です。

ワイワイしながらな感じですが、各マシン(参加者の方々)の走り(フィードバックの内容)は、エッジの効いたものばかりでした。

6/18(土)

2日目は、大阪本町の現地会場に移動して参加しました。

日本全国のアジャイルコミュニティがトラックを持ち、同時に幾つものセッションがオンラインで進行します。 タイムテーブル

大阪の会場では、各コミュニティ(トラック分)のipadが設置され、ipadにイヤホンを刺すことで、そのトラックで行われているセッションに参加出来る形です。 なかなか斬新…

どのセッションに参加するか悩んだのですが、下記のセッションに参加しました

組織の崩壊と再生、その中で何を考え、感じたのか。そして本当に必要だったもの

感想

現在、どんどん組織が拡大中の弊社ですが、いつか「うまくいかなくなる時」がやってくると思っています。

Rettyさんは、今でこそLeSSや自己組織化の浸透が進んでいるとのことですが、数年前まではツラい時期があったとのことです。

「崩壊しない組織より、適度なスクラップ&ビルドを乗り越えることが出来る組織の方が良い」という言葉は印象に残りました。

Managing for Happinessまもなく出版!プラクティス欲張り全部盛りジェットコースターワーク

感想

カンファレンスといえばワークショップ!ということで参加してみました。 90分でManagemnet3.0のワークをガンガンやっていくセッションです。

先日、オフサイトミーティングを開催し、メンバーがお互いに理解しあうアクティビティを行いましたが、このワークショップでは色々な角度からチームを掘り下げる方法を学ぶことが出来ました!

機会があれば、メンバーとManagement3.0のワークショップに参加して、弊社にも取り入れることが出来れば…!と思いました。

プロダクトってなに? マネジメントってなんなの? ゼロからプロダクトマネジメントを明らかにするぞ

感想

マネジメントとは?プロダクトとは?という根源的な問を、分析・明らかにするセッションでした。

スタートアップはプロダクトがすべてのところがあるので、再度、動画をじっくり見させて頂こうかと思います。

各登壇のスライドはスクラムマスダーさんがブログにまとめられているので、ご参考下さい!

他にも聞いてみたいセッションが山のようにあるので、動画が公開されるのが楽しみです。 しばらくはscrumfes漬けの日々になりそうです…

CSSフレームワーク「xstyled」について

こんにちは、Baseconnectのエンジニアインターンの大島です。 この記事では私が主に開発を行っているMusubuのフロントエンドの技術スタック、特にCSSフレームワークに注目して紹介したいと思います。

Musubuのスタイリング

Musubuの開発ではCSSフレームワークに、styled-componentsxstyledを用いて開発を行っています。

今回は聞き馴染みがない方が多いであろうxstyledについて注目し、Baseconnectでの使われ方も合わせて紹介したいと思います。

xstyledとは

xstyledはReact開発におけるpropsベースのCSS in JSフレームワークです。 styled-componentsやemotionに互換性があり、すでにこれらのCSS in JSを用いて開発を行っているプロダクトには簡単に導入ができます。

コンポーネント

import { x } from '@xstyled/styled-components'

type ButtonProps = typeof x.button.defaultProps & {
  leftIcon?: React.ReactNode
}

const Button = ({children, disabled, leftIcon, ...props}: ButtonProps) => {
  return (
    <x.button
      w="60px"
      fontWeight="bold"
      backgroundColor={disabled ? 'blue-500' : 'blue-400'}
      {...props}
    >
      {leftIcon && <IconWrapper>{lefIcon}</IconWrapper>}
      {children}
    </x.button>
  )
}

xstyledを使うことによるメリット

  1. utility first
  2. 命名コストがない
  3. presentational componentなのか、styled-componentなのか迷わない
  4. レスポンシブ対応や擬似クラスも容易に対応可能
  5. 開発速度の向上

などが挙げられます。一つずつ見ていきます。

1. utility first

xstyledでは、各タグに<x.*>をつけることでpropsでスタイルを当てることができます。そのため、事前にスタイルを当てるためのCSSを宣言する必要はありません。

また、カスタムCSSを一行も記述することなく、完全にカスタム化されたコンポーネントデザインを実装することができます。 たとえば、spaceXpropsであれば、通常以下のCSSを記述する必要がありますが、xstyledなら、1行で済みます。

--x-space-x-reverse: 0;
margin-right: calc({space} * var(--x-space-x-reverse));
margin-left: calc({space} * calc(1 - var(--x-space-x-reverse)));

2. 命名コストがない

これは私としてはかなり大きいメリットだと感じています。 styled-componentでは、それぞれstyleに対して命名する必要があるかと思います。これは開発者にとって脳に無駄なリソースを割くことになるため精神安定上良くないと思っています。 xstyledでは先の例で示したとおり、propsに渡すことでスタイルを当てることができるため命名の必要がありません。

これが解決できるだけでも十分なメリットがあると感じています。

3. presentational componentなのか、styled-componentなのか迷わない

styled-componentを使って開発を行っていると、これがstyled-componentなのか、presentationalなコンポーネントなのかがわからないということが頻繁に起こります。そのたびに、そのコンポーネントを参照してどちらなのかを確認することが必要になります。

命名規則をもたせることで解決できることもあるかもしれないですが、規則があったとしても命名コストはつきまとってきます。

xstyledならどのタグにどのスタイルがあたっているか一目瞭然となり見通しも良くなります。

4. レスポンシブ対応や擬似クラスも容易に対応可能

Musubuでは詳細な企業情報を扱ったり、営業リストを作成する機能を備えているため、モバイル端末をメインで扱っていません。 しかし、あらゆるユーザーを想定し、最低限のレスポンシブ対応を行っています。その際にxstyledは非常に容易に定義できます。

styled-componentの場合、メディアクエリを用いて以下のように定義する必要があるかと思います。

const Wrapper = styled.div`
  display: "block";
  background-color: "#fff";
    
  &:hover {
    background-color: "#000";
  }
    
  @media (min-width: 768px) {
    display: "flex";
  }
`
const ExampleComponent = () => {
  return (
    <Wrapper>
      <div>...</div>
      <div>...</div>
    </Wrapper>
  )
}

xstyledを用いることで簡潔に記述することができます。

// xstyledの場合
const ExampleComponent = () => {
  return (
    <x.div
      display={{
        _: "block",
        md: "flex"
      }}
      bg={{
        _: "#fff",
        hover: "#000"
      }}
    >
      <x.div>...</x.div>
      <x.div>...</x.div>
    </x.div>
  )
}

5. 開発速度の向上

xstyledはTypeScriptで開発されているため、型の恩恵を受けられます。そのため、styled-componentでよくあるtypoによってstyleが付与されないという問題を解決することができます。

また、styled-componentの場合、条件によって付与するスタイルが異なる場合、かなり冗長なコードになると思います。しかし、xstyledはpropsベースのため、条件分岐を簡単に書くことができます。

さらに、特に個人で開発を行う際など、colorやspaceなど全て自分で決めるのは少々面倒なこともあります。xstyledでは、v2以降TailwindCSSに影響を受けているため、デフォルトでいい感じのThemeファイルを用意してくれています。

xstyledのデメリット

ここまでメリットについて述べてきましたが、デメリットについてもいくつか上げたいと思います。

  1. コミュニティが他CSSライブラリと比べ活発ではない
  2. ドキュメントが少ない(Qiita, Zennでの検索ヒット数は合わせて1件)
  3. 複雑な疑似要素などを扱えない

これらの理由により、ある程度の規模のプロダクトでxstyled単体での利用は難しいと感じています。 そのため、styled-componentやemotionと併用して用いることで快適なフロントエンド開発を行えると思います。

Musubuでの活用事例

ここからは、Musubuでのxstyledの活用事例について紹介したいと思います。

theme file

xstyledではデフォルトでいい感じのthemeファイルを用意してくれています。 Musubuではデフォルトのthemeファイルを使わず、オーバーライドすることでデザインシステムを構築しています。

styled-component と xstyledの使い分け

Musubuではxstyledをベースに開発を行っています。しかし、先に述べたとおり、疑似要素を扱えないためbeforenot(:first-child)などを使いたいときにstyled-componentを使っています。 さらに、styled-componentを作成する際に@xstyled/styled-componentからimportすることで、xstyledの恩恵を受けながらstyled-componentで複雑な疑似要素を扱えるようになります。

import styled, { x } from '@xstyled/styled-component'

const Wrapper = styled(x.div)`
  &:before {
    ...
  }
`

const ExampleComponent = () => {
  return (
    <Wrapper w="1200px" bg="gray-100">
      ...
    </Wrapper>
  )
}

これにより最大限見通しを良くした状態でstyleを当てることが可能になります。

最後に

ここまで読んでいただきありがとうございます。Musubuのフロントエンド開発で用いられるCSSフレームワークについて書いてきました。

styled-componentemotionに辛みを感じている方にとって、何か役に立てましたら嬉しいです。

もし今後の技術選定に関わっていきたい方や、もう少し詳しい話を聞いてみたいという方、ぜひカジュアルにお話ししましょう! Baseconnectではエンジニアメンバーも絶賛募集しています。

meety.net

herp.careers

エンジニアでオフサイトミーティングを開催しました

プロダクト開発チームの富田です!

先日、オフサイトミーティングを開催したので、今回はそのことについて書こうと思います。

なぜ開催したの?

現在、Baseconnect全社で「戦略的内省期間」として、全部門で取り組みを行っています。

「戦略的内省」とは、下記のようなことと位置付けていますが、具体的にどんなことをするのかは各部門に一任されています。

・バリュー
・顧客価値
・顧客との対話
・メンバー同士の関係構築
・プロダクト価値に向き合う
・存在意義を問い直して深めること
・戦略を深く理解すること

等の長期的な成長に欠かせないこと(重要だが緊急性がないこと)に取り組む期間を作りたい。

開発では「メンバー間の相互理解を深める」ということをテーマにしました。

このテーマとなったのは「メンバーの人数が増えてきたことで、チームがバラバラに動いているように思える」と問題感が出たからでした。

どんな人が参加したの?

合計22名が参加しました。

どこで開催したの?

京都の岡崎庵で開催しました。

普段は結婚式場らしいですが、会議室としても利用することができます。

近くに平安神宮があったり、高級そうな料理屋が立ち並んでいたり、オフィスと同じ京都にありますが、イイ感じで気分転換出来る場所だったと思います。

関東に住んでいるメンバーも、この日は京都に来ていただきました。 久しぶりにリアルに会話することが出来て、それだけで盛り上がっていました!

何をしたの?

ウェルカム ワークショップ

最初に今回のオフサイトミーティングの目的とタイムテーブルの説明が終わった後、DPAのワークショップを行いました。

DPA(Design the Partnership Alliance)

4つのチームに分かれて座ってもらい、それぞれのチームで下記について話してもらいました。

  • どんな雰囲気でオフサイトMTGを進めたいですか?
  • その雰囲気を作り出すために何をしますか?

その後、各チームの代表者がどんなことを話したのかを発表してもらいました。

ファシリテータが意見をまとめ

  • 和やかに
  • 楽しく
  • リラックスして

という雰囲気で進めるということで、全員に同意してもらいました。


Value Card

その後、各チームでValue Cardを行いました。

これは、トランプのようにカードを使い、各メンバーがどんな価値感を大切にしているか明らかするアクティビティです。 ゲームに近い感覚で楽しむことが出来ます。

カードを捨てる毎に「それ大切にしないの?」「○○さんが捨てたその価値観、自分は重要だと思います!」というように、メンバーが何を大切にしているのか、逆に何を割り切っているのかコミュニケーションすることが出来ました。

ちなみに、私の場合は最終的にこんな価値観が残りました。

いつもの雰囲気そのままの結果の人もいるし、意外な結果な人もいるし、しばらく自己紹介の時にこの結果をネタに出来そうです。

ここまでで、午前中は終わりです。


インセプションデッキ(簡易版)

Value Card」で各個人感の相互理解が深まった(はず)ので、午後からは業務面に目を向けてみるアクティビティを行いました。

インセプションデッキは本来、プロジェクト毎の目線合わせや共通認識を作る手法かと思いますが、今回は、少し違った方向で行ってみました。

  • 作成するデッキは下記の4つです。(各内容は上記のリンクをご参考下さい)
・我々はなぜここにいるのか
・トレードオフスライダー
・夜も眠れなくなるような問題は何だろう
・やらないことリスト
  • 各受け持ちのプロジェクトではなく、Baseconnectのエンジニアとしてどうなのかという視点で考える

  • デッキを完成させるより、会話を楽しむことに注力する

また、デッキの内容毎にランダムに3つのチームに分かれ、下記のように進めました。

  • 質問についてチーム内で話し合う
  • 各チームから発表する
  • 全体でディスカッションする

1デッキ40〜50分、全体で4時間程となりました。

それぞれのテーマで白熱したディスカッションが行われ、最後のテーマでは全員ヘロヘロになっていました…

黙々と…

全体でディスカッション

印象的だった「愛」の付箋紙

ふりかえりと総括

インセプションデッキが終わった後、簡単に今日一日のふりかえりをしました

その後、部門責任者が締めの挨拶を行い、閉会となりました。


やってみてどうだったの?

直接的に何か業務に役立つことは難しいと思いますが、例えば

  • 新しいプロジェクトチームが編成された時、ValueCardをネタにコミュニケーションしてみる
  • SREやBI等、各チームでインセプションデッキを完成させてみる。また完成したデッキと、今回作ったデッキを比べてみる

等に利用出来るかもしれません。

いずれにしろ、自分自身や自分達について楽しくディスカッション出来たという「場の共有感」は、リモートメインの状況に於いては貴重だったかと思います。

一瞬マスクを外して記念写真

Baseconnectではエンジニアメンバーを絶賛募集しております。 もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います!

meety.net

herp.careers

Protocol Buffers でメッセージスキーマを管理する

こんにちは!エンジニアの大槻です。

Baseconnect ではたくさんのデータを保持していますが、単一のデータベースにそれらのデータを保存し、連携する各サービスからそのデータベースにアクセスする構成には、パフォーマンスその他多くの観点から問題があります。

それらの問題を解決するため、Baseconnect では複数のサービス間でデータを同期する方針をとっています。

データの同期には Amazon SQS や Amazon KinesisApache Kafka などのメッセージングシステムを用いますが、ここで問題になるのが、メッセージングシステムを介して送受信されるデータ(メッセージ)の形式をどう管理するかという点です。

候補としては Apache Avro や JSON Schema を挙げていましたが、エルデンリングのロード中にふと「Protocol Buffers が適しているのでは」と思いついたので、息抜きに試してみました。

実装の流れ

1. スキーマを定義する

まずは Protocol Buffers を用いてメッセージスキーマを定義します。

events/example.proto

syntax = "proto3";

package events;

option go_package = "github.com/ORGANIZATION/REPOSITORY/events";

message ExampleMessage {
    string id = 1;
    int64 timestamp = 2;
    string sentence = 3;
}

2. コードを生成する

先ほど定義したメッセージスキーマGolang その他のコードから扱うため、メッセージスキーマからコードを生成します。

$ protoc \
    -I ./events \
    --go_out ./events \
    --go_opt module=github.com/ORGANIZATION/REPOSITORY/events \
    ./events/*.proto

3. Kinesis Data Streams プロデューサーを作成する

先ほど Protocol Buffers で定義したスキーマからメッセージを作成し、メッセージングシステムにメッセージを送信します。

今回はメッセージングシステムに Kinesis Data Streams を用いますが、Amazon SQS など他のメッセージングシステムでも基本的な流れは変わりません。

cmd/producer/main.go

var client *kinesis.client

// ... 省略 ...

m := &events.ExampleMesssage{
    Id:        uuid.NewString(),
    Timestamp: time.Now().Unix(),
    Sentence:  "The quick brown fox jumps over the lazy dog.",
}

d, _ := proto.Marshal(m)

r := &kinesis.PutRecordInput{
    Data:         d,
    PartitionKey: aws.String(m.Id),
    StreamName:   aws.String("STREAM_NAME"),
}

res, _ := client.PutRecord(context.TODO(), r)

// ... 省略 ...

4. Kinesis Data Streams コンシューマーを作成する

最後にメッセージングシステムからメッセージを受信したら一連の流れは完了です。

cmd/consumer/main.go

var client *kinesis.client

// ... 省略 ...

res, _ := client.GetRecords(ctx, &kinesis.GetRecordsInput{
    ShardIterator: i,
})

for _, r := range res.Records {
    m := &events.ExampleMessage{}

    proto.Unmarshal(r.Data, m)
    
    fmt.Printf("%+v", m)
}

まとめ

Protocol Buffers でスキーマを定義し、Kinesis Data Streams 経由でメッセージを送受信してみました。

今回はメッセージングシステムに Kinesis Data Streams、プログラミング言語Golang を選択しましたが、他のメッセージングシステムやプログラミング言語でもほぼ同じ流れで実装できるかと思います。

Protocol Buffers は比較的馴染みがある、複数のプログラミング言語をサポートしている、後方互換性の担保をサポートしてくれるなど、メッセージングシステムと併用するうえで非常に便利な仕組みだと感じました。

今後はもっと実践的な内容で検証していきたいと思います。

Baseconnectではエンジニアメンバーを絶賛募集中です。 もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひご覧いただけますと嬉しく思います!

herp.careers

アジャイルを学ぶ「紙飛行機ワークショップ」を開催しました

こんにちは!エンジニアの富田です。Baseconnectは1つのビルをまるごとオフィスにしていて、1Fは大きなホールとなっています。

今回、この場所を使って、アジャイルについて学ぶ社内向けワークショップを開催しました。

ワークショップの内容は「各チームに分かれて紙飛行機を作ってもらい、どれだけ多くちゃんと飛ばせるか?」というものです。エンジニアを中心に8名の参加者だったので、2チームに分かれて行いました。(HRチームのエンジニア採用担当の寺尾も一緒に参加しました)


紙飛行機は以下のような作成ルールで作ります。

・ A4の紙をハサミで切って、1機につき1/4だけ使用して下さい
・ 1人が紙を連続して折るのは禁止です
・ 1度折ったら他のメンバーに紙を渡して下さい
・ 先端を丸めて下さい
・ 「飛行場」で3m以上飛んだら合格(納品)です
・ 再利用禁止
・ テスト飛行は1回につき1機だけ

また、作成は「セット」に分かれていて、それぞれの「セット」は計画・実施・検査と適応の書くフェーズがあります。

・  計画 2分
  ・ 計画後、納品数を見積もって下さい(各チームに確認します)
・ 実施 3分(飛行場で飛ばすのも込)
  ・ 実施後、納品数をカウントします(各チームに確認します)
・ 検査と適応 2分

この「セット」を4回行います。

最初に「皆さんは飛行機製造工場です。今回、より多くの納品を行えた工場が受注を獲得出来ます」というレクチャーを行いました。 単なるゲームではなく、「受注獲得のための大切な業務である」というわけです。


当日のタイムテーブルはこのような感じです。

導入・説明(10分)
ワークショップ(50分)
ダイアログ・対話(10分)
座学(20分)
ふりかえり

まずは、準備から。 「飛行場」を作ります。 手前の養生テープから飛行機を飛ばして、向こうのテーブルまで届けば合格です。

レクチャー中

みんな真剣です

投げます!

届いた!


ファシリテーターから各チームに、3セット目はルールを1つ外して良いということが知らされます。

何のルールを外すと、より効率的に合格数を上げることが出来るか、各チームで考えました。

その結果、

・ チームA:「1人で連続して折ってOK」
・ チームB:「先端を丸めなくて良い」

ということにしました。

上記の条件で3セット目は行われ、各チーム共、生産数が跳ね上がりました!

(途中からの参加者が居たため、慣れてもらうために2セット目と3セット目の間に1セット余分に行いました)

結果を見てみると、だんだんと合格数が上がっていている! 反面、あまり見積もりとの乖離がなく、大きな改善目標を持って挑戦する姿勢が薄い印象もありました。


実施後はアジャイルについて座学で学びました。

・ 繰り返し開発について
・ 経験について
・ ふりかえりについて
・ 3セット目で外したルールについて(制約)
・ ムダの話

また、作業環境を見直すことで、多少でも生産効率を伸ばすことができることが出来たのでは?という話もしました。


最後に簡単に今回のワークショップについて、ふりかえりました。

良かったこととして、下記のような事が挙がっていました。

・ 準備が出来ていた
・ いろんな人にやって欲しいと感じた
・ アジャイルの概要が分かりやすかった
・ 競争が良かった

また、もっと良く出来そうな事として下記のような事が挙がっていました。

・ 大胆なチャレンジが出来ていなかった
・ 4回目の結果で判断しても良かったのでは?
・ 抜け道を防いで欲しい
・ 回数がもっと有っても良かった
・ 要件の整理フェーズが有っても良かった
・ お互いの戦略を聞きたかった

次回開催する時は、参考にさせて頂きたいと思います。

(汚い字でスイマセン)

「もっとよく出来る」で出た中に「抜け道」というのがあるのですが、これは、参加者の一人から「紙をグチャグチャに丸めてしまって投げて良いですか?」と質問があったことです。

納品の合格ラインとしては「3m飛ばす」ということなので、「飛行機」の形状に関わらず、その点ではクリアすれば良いのですが、納品物としてはどうなのか?

作業の開始前に、どのような納品物を想定しているのか?こんなものでもいいのか?あんなものでなければいけないのか?など、すり合わせが必要だったかもしれません。 また、これは、今回のワークショップに限ったことではなく、開発業務でも必要なことかと思います。

今回の経験を踏まえて「紙飛行機ワークショップ」をまた別メンバーで開催出来ればと思います!

Baseconnectではエンジニアメンバーを絶賛募集しております! もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います!

meety.net

herp.careers

アルゴリズムにおけるTime Complexity (時間計算量)について

こんにちは、BaseconnectのエンジニアのEndratno Alvinです! 本日は、アルゴリズムの性能を評価するための概念を紹介したいと思います。

Time Complexity (時間計算量) とは?なぜ必要なのか?

あるアルゴリズムの速度を特定するために、実行時間を測定することはほとんどの状況において適切な方法とはなりません。なぜなら、測定結果はCPUの速度、データ量などの外的要因の影響を受けるからです。そのため、私たちには外的要因に依存せず、アルゴリズムの速度を評価する方法が必要になります。それがTime Complexity (時間計算量)です。Time Complexityは、多くの場合 Big O Notation(ビッグ オー記法)で表すことができます。

Big O Notion

概念

Big Oは、アルゴリズムが小さいサイズの入力でどれだけうまく機能するかを評価しません。 大きなデータを入れた場合に実行速度がどうなるかによって、時間計算量が変わります。

多くの場合、Big O表記法は、アルゴリズムの最悪のシナリオを表現します。 つまり、実行数(ループ数など)が一番多くの場合を考えて、それの係る時間を表しています。

係数と定数

従って、Big Oで記述するときに、実行時間の係数と定数は考慮しません。例えば、一つのデータの処理時間は5秒であっても、10秒であっても、実行時間のグラフで表す線の曲が同じである限り、時間計算量は同じです。

また、Big O を特定するために、処理を実行する前に必要な準備時間などの定数も考慮しません。なぜなら、データが大量になると全体の処理時間が長くなり、準備時間の影響が小さくなり誤差とみなせるようになるからです。

例で考える、実際に時間計算量を求めてみましょう

Linear Time Complexity (O(n))

箱を想像してみましょう。4つの箱があるとします。その4つの箱の1つに宝が入っています。他の箱には何も入っていないとします。

宝を探すには箱を開けて、確認して、宝を見つかるまで繰り返していきます。1箱を開ける必要な時間は2秒とすれば、4つの箱を開ける必要な時間は8秒です。40個の箱を開けるのに必要な時間は80秒です。箱の数が増えれば宝探しにかかる時間も増えます。

箱を開けるのに必要な時間 x 箱数

箱を開けるために必要な時間(処理時間)をOにして、箱の数(データ量)をnとすれば、このアルゴリズムの時間計算量はO(n)で表すことができます。

Quadratic Time Complexity O(n2)

他の場面を考えてみましょう。 同じく箱があって、その箱の中に1箱に宝があるとします。しかし、今回は箱をあけるために鍵が必要になります。鍵は全箱分あります。一つの鍵で一つの箱を開けられるとは限りません。

最悪の場合、すべての箱を確認する必要があります。従って、一つの宝箱に対し、全部の鍵を試すを必要があります。鍵を試すのに2秒かかるとすれば、最悪の場合、4つの箱場合は4つの鍵 x 4つの箱 x 2秒の時間が必要です。まとめると下記になります。

箱を開ける必要な時間 x 鍵の数(箱の数と同じ) x 箱の数

前と同じ方法で、Big O で表せば O(鍵数 x 箱数)なので O(n2) になります。

Constant Time Complexity O(1)

時間計算量を求めるのに慣れていただけましたでしょうか。以下は時間計算量を最小にするベストなアルゴリズムのTime Complexityを紹介したいと思います。 上記と同じ場面ですが、今回は犬を使って、宝を特定することにしました。その犬は「宝を特定する」という特別な才能を持っていることとします。

どれだけ宝箱があっても、一発で特定できる犬がいるおかげで、すぐに宝が入った宝箱を見つけることができます。

この場合、データ数に関係なく、実行時間が同じになります。この場合はO(1)と表すことができます。

Exponential Time Complexity O(kn)

もう少し応用的な使い方も紹介します。 宝箱を開けるためにn桁の暗証番号を特定する必要がある場合の時間計算量はO(kn)となります。

kは桁の進数です。nは桁数です。10進数の8桁であれば、108通りを試す必要があります。この場合は O(kn)で表すことができます。

Cubic Time Complexity O(n3)

次に、宝箱の鍵に鍵が掛かっている場合を考えましょう。プログラミングの目線で言えばループの中にループがあるい場合となり、 O(n3)で表せます。

Linearithmic Time Complexity O(n log n)

上記のO(n2)と同じようなケースですが、今回は、一つの鍵で一つの箱しか開けられないことがわかったとします。 ある鍵で箱を開けた後、その鍵は他の箱を開けられることがないため、鍵を捨てることができます。箱を開けるたびに、試す鍵が少なくなります。 従って、箱を開けるためにかかる時間が箱を開けていく毎に減少していくことになります。

上記のTime Complexityは O(n log n)で表すことができます。O(n2)よりは早いですが、O(n)より遅くなります。

Logarithmic Time Complexity O(log n)

宝箱のうちに半分を一度で探すツールがある場合は時間計算量はO(log n)になります。

まとめ

Time Complexity の「悪い」から「良い」順に並べれば、以下の順になります:

  1. O(kn)
  2. O(n3)
  3. O(n2)
  4. O(n log n)
  5. O(n)
  6. O( log n)
  7. O(1)

おわりに

開発者はより良いプログラムは誰でも書きたいと思います。プログラムを書く際に、特別な才能を持つ犬や一度でに半分を探すツールを取り入れられるかどうか、使った鍵をまた試しているかどうか、最善の時間計算量を使うことを意識することはより良いプログラムを作ることにつながると考えています。

Baseconnectではエンジニアメンバーを絶賛募集中です。 もしご興味をお持ちいただけた方がいらっしゃいましたら、下記のリンクよりぜひカジュアルにお話しさせていただけましたら嬉しく思います!

meety.net

herp.careers