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ではエンジニアメンバーも絶賛募集しています。

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

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

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

herp.careers

大学二回生がインターンとして入社し半年が経った話

初めまして、Baseconnectのエンジニアインターンの秀と申します。今回は現在大学二回生である僕が、半年間勤めて初心者ながらも気づいたことや、感じたことをお話ししようと思います。 (執筆時点で二回生、この4月で三回生になります)

はじめに

まずは、僕自身とBaseconnectのエンジニアインターンについて軽く紹介しておこうと思います。冒頭でも少し触れた通り、僕は現在大学二回生で文理混合の情報学部に通っています。

元々情報系に興味があったので、Baseconnectに入社する前から一応教本などでプログラミングの勉強はしていましたが、小さい頃からコンピューターを触っているような人間ではありませんでした。

参加したきっかけはコロナの影響が大きかったと思います。大学入学直後から講義はほとんどリモートで、出される課題は多いものの意外と自分に使える時間が沢山ありました。そんな中、見かけたのがBaseconnectのエンジニアインターン募集の記事でした。

他のサマーインターンなどと違って、期間が決められておらず最短で15ヶ月以上と長期的です。仕事に慣れてくるとリモートでの勤務も可能なので働き方には融通が効きます。僕は、ただただ課題をこなす日々を変えたくて、応募を決意しました。

その1...触れるコード量が多い

晴れてBaseconnectに入社でき、いざ初めのタスクに取り掛かるぞ!と息巻いたところ、コード量の多さに圧倒されました。ディレクトリはしっかりと階層構造で分けられていたものの、教本や映像教材でも見たことのない単語がずっしり......。最初に振られたタスクはとても簡単なものでしたが、変更箇所を探すだけでも一苦労でした。

その2...ツールの重要性

早速エンジニアとしての洗礼を受けた僕ですが、いくつかタスクをこなしたり、先輩達のありがたいアドバイスを受け、徐々に徐々にコツを掴んでいきました。その一つがズバリ検索です!!先ほど、簡単なタスクでも変更箇所を探すだけで苦労したとお話ししました。

しかしこの問題...テキストエディタの検索機能を使えば一発で解決します!!と言っても世のエンジニアの方からするとこれは当たり前の手段でわざわざ本やブログなんかに書くことでもないかと思います。

しかし、大量のコードに触れた事がなく、これまで手探りでコードを探しても困らなかった僕には無かった発想でした。この時ぐらいから今まで使っていたツールを見直し、ショートカットを覚え、真の意味でツールを使い始めました。

その3...複数人での開発

ある程度業務に慣れ、多少は周りに目を向ける余裕が出来た頃、ふと思ったのが複数人での開発はやはり個人のとは違うということです。

個人で好きなようにアプリケーションを作ってみたり、教本のコードを写経していた時というのは他人の目を気にする必要がなかったので、ファイル名・メソッド名・変数名が何であろうが自分が理解できれば関係ありませんでした。テストコードも大して書いておらず、フォーマッターやリンターなどは概念すら知らなかったです。

そんな僕だったので、Rspecをちゃんと書いたり、rubocopを通したりというのはBaseconnectに入って初めての経験でした。ですが、やはり複数人での開発を意識したコードは圧倒的に見やすく、レビューが入ることを考えても効率的です。

その4...マネジメントの意識が高い

業界の色なのでしょうか、Baseconnectに入社して一番驚いたのがこのマネジメントの意識の高さでした。僕自身昭和チックな指導スタイルの体育会系部活に長年所属していたこともあって、ちゃんとした本物のマネジメントらしいマネジメントを初めて受けて、本当に感動しました。

今、日次でデイリーミーティングを、隔週で振り返りを行っているのですが、部活をやっていた頃は怒鳴られ叫ばれは日常茶飯事でしたが、ここではそんな事は一切なく、失敗した時でも理論的に解決方法を探り、関係性の向上をモットーに改善を意識したサイクルを心掛けています。

人によっては昭和テイストのマネジメントが合う方もいると思います。しかし、僕の場合はこちらのやり方の方が確実に成長出来ていると思います。

最後に

恥ずかしながら、Baseconnectに入りたての感覚をそのまま書き綴ってみました。まだ実務を経験した事がない方には実際の様子が少しでも伝われば嬉しいです。つよつよエンジニアの方には、駆け出しのメンバーがどんなことを考えているのか少しでも伝われば嬉しいです。拙い文章の中、ここまで読んでいただきありがとうございました。