Septeni Engineer's Blog

セプテーニエンジニアが綴る技術ブログ

スマフォを捨てて、1ヶ月が経ちました。

0. 前置き

どうも、初めての方ははじめまして、お久しぶりですの方はお久しぶりです。エンジニアの原田です。
ネタとして温めていたたわけでも無いんですが、個人端末についてでもお話しようかと思います。
結果、この持ち方が最高とか、賞賛するわけではないのですが、読み物的に楽しんでもらえれば幸いです。

1. なぜスマフォを捨てたのか?

どうしてスマフォを捨てようと考えたのかについてです。
スマフォに対して大きな不満はなかったのですが、決めてになった変更理由についてです。

続きを読む

scikit-learnを使ってみた

こんにちは、佐野です。

先日、機械学習を勉強する機会があり、手元でちょっと検証するときにscikit-learnを使ってみたのですが、とても使いやすく便利だったため、有名なライブラリですが紹介したいと思います。

scikit-learnとはPythonオープンソースライブラリで、クラス分類、回帰分析、クラスタリングなどのための様々なアルゴリズムを備えた機械学習ライブラリです。

Pythonを今まで書いたことがなかったし、機械学習も薄っぺらい知識しかなかった僕でもインターフェースがとてもシンプルな作りになっていたのですぐ馴染むことができました。

続きを読む

ITS健康保険の保養施設に行ってきました

こんにちは、池田です。

セプテーニ・オリジナルは2016年7月より関東ITソフトウェア健康保険組合(以下、ITS健康保険)という健康保険に編入しました。

先日この健康保険で使える保養施設「トスラブ箱根ビオーレ」に行ってきまして、

大変良かったので簡単にご紹介したいと思います。

f:id:taketor:20170707033526j:plain:w500

▲ 宿泊した洋室

続きを読む

scala.concurrent.blocking()

こんにちは。3月にセプテーニ・オリジナルに入社した河内です。 新しい環境でフレッシュな気持ちで業務に取り組んでおります。

さて scala.concurrent.blocking() は全く新しくない話ですが、あまり知られていないのかな、と感じるので書いておきます。 scala.concurrent.blocking()ブロッキング処理をマークするのに使います。

実行中のスレッドに関連付けられた *1 BlockContext によっていい感じに取り扱われます。 デフォルトの BlockContext は渡された引数を単に評価するだけです*2

BlockContext.withBlockContext() を使うと、指定した BlockContext を使ってブロッキング処理を扱うことができます。 次の例では blocking 前に log を出す BlockContext を作って利用しています。withBlockContext() で指定することで blocking() で囲まれた処理を実行する前に log が出力されます。

    val logContext = new BlockContext {
      override def blockOn[T](thunk: => T)(implicit permission: CanAwait): T = {
        println("Start blocking")
        thunk
      }
    }

    BlockContext.withBlockContext(logContext) {
      blocking {
        println("Blocking code")
      }
    }

withBlockContext() を使って BlockContext を自分で指定することは少ないと思います。おそらく最もよく出てくる場面は ExecutionContext.Implicits.global (以下 global) の上で Future を走らせるときではないでしょうか。

globaljava.util.concurrent.ForkJoinPool を用いて実装されています。ForkJoinPool は限られたスレッドを使ってCPUを効率的に利用する仕組みですが、ブロッキング処理が混ざるとCPUを効率的に利用できません。そこで登場するのが ForkJoinPool.ManagedBlocker です。この中でブロッキング処理を実行すると、専用のスレッドが起動されるため、元々の限られたスレッドは別の計算を行うために引き続き利用できます。

blocking() を使わずに global 上でブロッキング処理を行うと、CPUを効率的に利用できません。 global 上で blocking() を実行すると ForkJoinPool.ManagedBlocker を利用して内部の処理を行います。 これにより global 上でも CPU を効率的に利用できる環境が保てます。

デフォルトではそのまま実行され、global などの環境では専用スレッドを起こしてくれるので、ブロッキング処理は blocking() で囲みましょう。。。

で、話が終わればいいのですが、 Scala 2.11 以前では気をつけなければならない事項があります。

まず、できるだけ blocking() の中で blocking() を呼ばないこと。 global では blocking() を呼び出したときにスレッド (Thread1) が作られ、その中で再度 blocking() を呼び出すと別のスレッド (Thread2) が作られます。 Thread2 上での処理が完了するまで Thread1 は遊んだ状態になります。 なるべく下の層で blocking() を使うのが良いでしょう。

次に、blocking() を並列にたくさん呼びすぎないこと。 ブロッキング処理用に作られるスレッド数には事実上制限がないため、一時に多くの blocking() を呼び出すと作ることができるスレッドの限度を超え、 OutOfMemory エラーが発生します*3

Scala 2.12 では上記二点が改善されています。 ネストした blocking() 呼び出しにより余計にスレッドが作られてしまうことはありません。 スレッド数は 256 が最大に設定されており、 scala.concurrent.context.maxExtraThreads システムプロパティで変更できます*4

接続先ごとに ExecutionContext を利用するのがベストプラクティスだと思いますが、小さい単位の関数を書いていると、実行時に使われる ExecutionContext (BlockContext) が限定できないという状況があると思います。 ブロッキングしなければならないとき*5には blocking() を使うと、global を使った場合でも全スレッドをブロックしてしまう事象が置きづらく、良いと思います。

*1:ThreadLocal や Thread.currentThread が参照されます。詳しくは BlockContext.current を参照。

*2:BlockContext.DefaultBlockContext、Scala 2.12 では BlockContext.defaultBlockContext を参照

*3:参考: blockingとOOM

*4:参考: Futures in Scala 2.12 (part 7)

*5:避けられる限りブロッキングしないようにしましょう

制約条件の活用について

こんにちは、スクラムマスターやってます貫名です。

現在弊社ではodd-e Japanアジャイルコーチの江端氏に文字通りコーチング頂き、絶賛チーム開発へのテコ入れを実施しています。この期間の学びは多岐に渡りますが、その中でもタイトルに出した「制約条件の活用」はスクラムマスターとしての立場を取っている私にとって特に影響力が大きなテーマでありましたので、駄文ではありますが体験についてご紹介させて頂きます。(今日書く内容は、実際に経験したことに対して私の解釈を加えた内容となります点ご了承ください)

自分の子供に対して、本人が望むならどんなことでも経験させますか?

仕事終わりに飲みながらなシチュエーションで出てきた類の話ですが、スクラムマスターとしての在り方に関する話をしていて子育てを例に話が深まっていきました。お子さんが居る方は言葉のままに、いない方でも想像の中で良いのでこの質問になんて答えるか考えてみて頂けないでしょうか。

この話の背景には “教えることよりも、本人自らが気づいたことによるその後の学び・成長の大きさ” みたいな話があって、この考えを極端に解釈していた私の回答は

「自分の子供が自ら選択するなら、どんな経験をしたとしても構わない(と言いたい!)」

といったものでした。言い換えれば子供が気づくまで見守り続けるスタンスのつもりなのですが、実際の自分の子育て(現在2歳児の父)を振り返っても、将来子供が大きくなった時を想像しても、まぁそんなはずないなと。超えちゃいけない一線?とでもいうのでしょうか、あるなぁと。

多様な背景を持つ30人弱の集団で結論がなかなか出ない、さぁどうする?

こういった場面に出くわすくことはないでしょうか?30人はなくても、もっと少ない人数・2人であっても議論が平行線をたどってなかなか結論が出せない場面であればOKです。司会だろうと、議論の参加者だろうとどっちでも良いので、あなたならどう振る舞うかを考えてください。

ちなみに私もこういう場面に出くわすことは少なく無いのですが、仕事でこういった場面に出くわした場合によく私がとっていた行動/思考が

「決め方のルールが決まって無いから前進してないはず、なのでルール決めよう」

と考え行動します。どのアプローチが正解か・間違いかという話ではないですが、これも1つの選択だと思っています。ただよくありがちかと思うのがこの「決め方のルール」を決めること自体にも時間をかけてしまうケースです。どんな規模であれ、意思決定をスムーズに進行する集団は、決める上での基準みたいなもの?がはっきりしてるんじゃないかと思います。

「より良いもの」の前の「許容できないもの」

多様な見方ができるとは思いますが、子供への経験の話は “より良い学び・成長” を意図してるわけですし、集団での議論の話も個々人の参加者は “より良い回答” を集団が選ぶよう主張なりをしていると思われます。

この「より良い」がなかなか曲者で、子育てで言えばどのタイムスパンで考えるかによって選択に対する評価は変わるかもですし、集団の議論で言えば参加者一人一人の評価は異なっているのがむしろ普通だったりします。この時に着目してみて良いかも知れないと学んだのが、

「許容できないもの」

です。子育てで言えばどんなに子供が自分で選んだとは言え「他人や自分の命を危険にさらすこと」は冗談抜きで親である私にとっては許容できないことの1つになると思っています。集団の議論の場ではどうでしょう?これは時と場合によって異なってくるので例は割愛させて頂きます。

この「許容できないもの = 制約条件」と私は解釈しているのですが、このラインを適切にひくことでそれ以外の部分では思う存分自由に行動/思考できる状態を作ることこそが、牧羊犬と言い表されるスクラムマスターに求められることの1つかも知れません。

ペアプログラミングの勧め

みなさま、こんにちは。

昨年、11月に中途で入社しました堀越というものでございます。

つい最近のお話ですが、業務でペアプログラミングなるものを実施しました。

良いなと感じる点が多かったので説明も兼ねて共有します。

ペアプログラミング

2人のプログラマが1台のワークステーションを使って共同でソフトウェア開発を行う手法である。一方が単体テストを打ち込んでいるときに、もう一方がそのテストを通るクラスについて考えるといったように、相補的な作業をする。

引用元:ペアプログラミング - Wikipedia

ペアプログラミング実施の背景

弊社では、4月よりスクラムの取り組みを改善する施策をしており、

目標の一つに複数の開発チームがそれぞれが所有する開発タスクを

チーム間を跨いで対応可能にするというものがあります。

ただし、その為には他のチームが抱えるプロダクトや業務に関する知識が備わっている前提となるため、

この課題に対する一部アクションとして他チームメンバとペアプログラミングの実施に至ったという背景があります。

ペアプログラミングを始める前に

1. パートナーを探す

ペアプログラミングは1人ではできません。

勇気を出して気になるあの子を誘ってみましょう。

2. ドライバーとナビゲータに分担する

ペアプログラミングは2人で作業を進めるとはいうものの、

端末を一台しか使いませんのでドライバーとナビゲータを決めましょう。

ドライバはコードを書く人、ナビゲータは作業指示をする人というのが私の理解ですが、

ナビゲータは作業指示ではなく、作業を促すようなコメントをするのが良いとする文献もあるようです。

3. ドライバーとナビゲータの交代サイクル

作業分担が長時間同じだと疲れてしまうので、

ドライバーとナビゲータの交代時間を決めましょう。

私の場合、おおよそ30分間隔だったと記憶しています。

4. 着手する作業を決める

作業を開始してから何するか考えるのは時間がもったいないですね。

あらかじめ着手する作業内容を決めておきましょう。

その際、どこまでの作業をゴールとするのか目標設定しておくと尚良いでしょう

実際にやってみて良いなと思った点

開発Tipsを共有できる

CUI のコマンドや、IDEのショートカットに何を使うか等の

細かいキーボード操作や、仕事の仕方など実際に一人で作業していると

なかなか共有する機会が無いと思います。

ペアプログラミングをしていく中でパートナーの作業風景から

得るものが少なからずあると思います。

私はこの結果、生産性が3倍向上した気持ちになりました。

一人よりも二人のほうが問題解決できることが多い

1人で作業していたら時間がかかっていた、ハマっていたであろうことが、

2人で立ち向かうことでさほど問題にならないことが多いと思います。

何かの問題に直面した際、パートナーに状況を説明することで、

頭が整理されて自己解決したなんてこともあると思います。

プルリクに出すコードの品質があがる

ドライバーがコードを書いている最中、ナビゲータはコードレビューする形になるので、

実装不備があった時点ですぐに指摘することができます。

そのため、プルリクを出す時点である程度品質が担保された状態になります。

所感

個人的には自身の成長につながる部分が多かったのでペアプログラミングお勧めです。

ただし、成果物を出すのに2人分のリソースを割くので全体での時間はかかっているかもしませんし、

一人で作業することを好み、自身の作業スタイルを貫きたいエンジニアにとっては、

ストレスに感じてしまうところもあるかもしれません。

メリット、デメリットを考慮して、必要に応じて実施するのが良いのではないでしょうか。

最後に

僕とペアプロ…、しませんか?

お誘いお待ちしてます。