最近の 1on1 について

どんな場所にいようと、どんな立場だろうと、年齢、性別、所属、関係なく人は常に悩み、常に選択し生きている。 悩みを解決することが目的ではなくとも、聞いてもらえるだけで、肩の荷が降りることもある。

現在の私は キャリア形成や組織云々に関しての興味がやや薄めなのだが、 最近ふと見た Youtube で、1on1 に対しての再確認/再発見な考え方があったので、個人的に書き残しておく。 なぜなら、確実にこれらも一つの スキル なんだよな...と最近理解できるようになったので。。。

URL

Memo

hidek氏:

  • will/can/must フレームワークを使う
    • will/can/must とは?: https://www.recruit-ms.co.jp/issue/feature/soshiki/201112/02.html
    • will(やりたいこと)、can(できること)、must(すべきこと)
    • 3つの円が重なる部分が最も活躍できる領域
    • can/must は一緒に働いているとある程度見えるが、will は聞かないと分からない。1on1 で特に話す。
  • 信頼関係を構築する
    • 自分が何をやっているのか近況を話す(マネージャーが何をやっているのか)
  • 期待値を擦り合わせする
    • 評価のサプライズ(極端に上げる/下げる)はしないようにする
    • サプライズは評価として響かないので、評価面談時には、「いつも言ってるよね」くらいの認識にする
  • EX: 泥臭いけど、出社時にオフィス巡回して声かけてる
    • プロジェクトやレポートラインの人とは、オンラインでもコミュニケーション頻度は変わらないが、ビジネスサイドやコーポレートなどの部署の人とはコミュニケーション接点が切れる

BTO氏:

  • 「信頼関係の構築、課題の早期発見、経験学習の促進」を 1on1 の目的として置いている
    • 信頼関係の構築は、一緒に会話したり過ごす時間が長いほど自然と構築されていくので、やるだけ
    • 課題の早期発見は、火種が小さいうちに発見するため
    • 経験学習の促進は、コーチング的な側面で。コーチング的なフレームワーク等を使わないと人は成長するのが難しい。
  • EX: EM に現場のメンバーと不定期に 1on1 をしてもらって、レポートライン直下以外の経由で情報を吸いあげる経路を作る。課題の早期発見を図る。
    • その人自身の課題/問題点は、その人からは出てこない。別のパスで情報を抽出/ヒアリングする。

1on1 には、色々な本も出ているし、事前にアジェンダを用意しましょう、やアジェンダなく雑談しましょうなど正解がないように思う。
が、やった方が良いとは全員思っている。とのこと。


ふと数年前、書店でOKRの本を見かけて購入し上司にお願いして試したりもしたので、書き残す。
自分に適した、上手いやり方は見つけられなかったけど、部分的に賛同できる内容だった。

OKR(オーケーアール) | クリスティーナ・ウォドキー, 二木 夢子, 及川卓也 | 実践経営・リーダーシップ | Kindleストア | Amazon

お気持ち供養

内容

色々と人生の節目な気がし、\ナイストライ/しようと部署異動を決意しました。
結構マジですごくかなりめちゃくちゃ悩みましたが、あまり悩まなかったようにも思います。その理由を書き残しておきます。

なぜ部署異動しようと思ったのか

  • 仕事でインフラ周りに関する技術の(知識や) 経験 が必要だと感じたため
  • 私事で将来的にやりたいことに対して、これらの知見が必要になるだろうと感じたため

仕事でインフラ周りに関する技術の(知識や)経験が必要だと感じたため

端的に言うと、この辺りのより詳細な会話が出来ないandタスクを手伝えないand考慮して開発できない(同じゴール景色が見えない)自分が不甲斐ないと常に思うようになってしまいました。なので、必要だと感じています。

これまで開発陣等々には、毎度この辺りをまるっとお願いしていたため、切なさと申し訳なさと色々な何かが...溢れてしまいました。もう人生で何回同じようなことで同じように悩んでDRYだし、ややYAGNIするんだろう...学ばないスタイル。自分使えねぇなって毎回思います。
また、エンジニアとして今後やっていく上で 私は この辺りの基礎的な部分はもちろんのこと、少し踏み込んだ部分も must で必要だと思うので、ただただチャレンジして、(小さく)失敗して、たくさん経験を積みたいと思います。上手い階段の登り方や道筋は分かってません。

私事で将来的にやりたいことに対して、これらの知見が必要になるだろうと感じたため

端的に言うと、自分より若い世代の方(特に子供たち)に対して、技術を使って何か役に立つことをしたいなぁと漠然と考えるようになりました。そのために、必要だと感じています。

2年前くらいに、親友の赤ちゃんが生まれ、抱っこさせてもらう機会がありました。まだこの世に降り立って数ヶ月でした(よく抱っこさせたな)。すごく小さくてすごく暖かくて、気を抜いたらすぐ落っことして壊れそうで、目は空いてないし、全然動かないけどしっかり生きてることに不思議と感動してしまって、「あ、こういう子達のためなら命削ってもいいな」って思っちゃいました。

最後に

実は他にも、せっかくなので社内の色々な人と働いてみたいと思っていたり、私事で人生の大きなイベントが終わったり、技術的なモチベがあったり、などもあるのですが、大きくはこのような理由から決意したのでした。

React (+ Redux) ライフサイクル

公式を読んでいきます! 各セクション TL;DR で

State and Lifecycle

React コンポーネントの状態とライフサイクルの概念について。

Classで書く

React.Component にClockクラスを拡張する。 関数の本体を render() メソッドに定義していて、this.props で値を取得して render()

render() メソッドは、更新が行われるたびに呼び出される。 下記の例では、<Clock /> が、同じDOMノードにレンダリングする限り、 そのClockクラスのインスタンスは1つだけ使用される。

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2> // this.props で取得
      </div>
    );
  }
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

Local state を使う

this.props.date と this.state.date して render() する方法

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

ライフサイクルメソッドをクラスに追加する

多くのコンポーネントを持つアプリケーションでは、コンポーネントが破壊されたときにリソースを解放することが非常に重要だ

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  
  // DOMにレンダリングされた後にフックが行われる
  componentDidMount() { // タイマーセット(マウント処理)
    this.timerID = setInterval( // this.でアクセスしてtimerID を保存
      () => this.tick(), 
      1000
    );
  }

  componentWillUnmount() { // タイマークリア(アンマウント処理)
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />, // Clockコンポーネントのコンストラクタを呼び出す
  document.getElementById('root')
);

状態を正しく使用する

// wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});

状態の更新を非同期で行う

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
// 第1引数がstate, 第2引数が更新後のオブジェクト等
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

状態の更新を適用

constructor(props) {
    super(props);
    this.state = {
        posts: [],
        comments: []
    };
}

componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }

データフローダウン

これは、通常、「トップダウン」または「一方向」データフローと呼ばれます。すべての状態は常に特定のコンポーネントによって所有され、 その状態から派生したデータまたはUIはツリー内のコンポーネントの「下」にしか影響を与えません。 コンポーネントツリーを小道具の滝として想像すると、各コンポーネントの状態は、任意の点でそれを結合する追加の水源のようですが、流れ落ちます。

function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <FormattedDate date={this.state.date} />
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

React.Component

コンポーネントライフサイクル ライフサイクルメソッドの公式チートシート http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

コンポーネントインスタンスを作成してDOMに挿入するときに呼ばれるメソッドについて

constructor() static getDerivedStateFromProps() render() componentDidMount()

※ 非同期レンダリングのライフサイクルについて https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

状態の変更(更新)

static getDerivedStateFromProps() shouldComponentUpdate() render() getSnapshotBeforeUpdate() componentDidUpdate()

アンマウント

コンポーネントがDOMから削除されるとき componentWillUnmount()

一般的に使われるライフサイクルメソッド

https://reactjs.org/docs/react-component.html#reference

参考: https://reactjs.org/docs/react-component.html

Redux Todos Example

公式: https://redux.js.org/basics/example-todo-list GitHub: https://github.com/reduxjs/redux/tree/master/examples/todos

Redux Todos Example を読み解く 参考: https://intheweb.io/react-redux-todos/

React Redux

【C#】多次元配列とLINQ

探索のメモ化と動的計画法を扱う上での基礎知識として。

配列

配列 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

2次元配列とLINQ

C#の2次元配列とLINQ - やっさんの雑記

多次元配列をLINQで扱う

多次元配列を LINQ で簡単に扱おう - xin9le.net

拡張メソッドを扱う場合は、静的クラス中に、 第一引数に this キーワードを修飾子として付けた static メソッドを書く 必要がある。
参考:拡張メソッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

蟻本/ナップサック問題再帰を使用した例をC#

using System;

namespace Program
{
    class Program
    {
        const int n = 4;
        const int W = 5;

        readonly int[,] data = {
            { 2, 3 },
            { 1, 2 },
            { 3, 4 },
            { 2, 2 }
        };

        static void Main(string[] arg)
        {
            var p = new Program();
            var dp = new int[p.data.GetLength(0) + 1, W + 1];

            var result = p.rec(0, W, ref dp);
            Console.WriteLine("{0}", result);
        }

        public int rec(int i, int j, ref int[,] dp)
        {
            var res = 0;
            if (i == n)
            {
                res = 0;
            }
            else if (j < data[i, 0])
            {
                res = rec(i + 1, j, ref dp);
            }
            else
            {
                res = Math.Max(rec(i + 1, j, ref dp), rec(i + 1, j - data[i, 0], ref dp) + data[i, 1]);
            }

            return dp[i, j] = res;
        }

    }
}

出力: 7

memset での初期化をC#でどう書けばいいのかは分からなかった...

【CircleCI】ASP.NET Core 2.0, xUnit を使用したテスト

前提

環境とコードは、下記の記事を参考に動かします。
【C#】xUnitを使用した単体テスト - 小さいことの積み重ね

CircleCIの導入

こちらの記事を参考にさせていただきました。
GitHubアカウントさえ用意しておけば、簡単に登録できます!
【CircleCI】CircleCI 2.0からはじめる個人での簡単なCI導入方法 - githubとの連携まで - tweeeetyのぶろぐ的めも

config.yml の設定

ASP.NET Core を使った、.ymlファイルの設定です。

version: 2
jobs:
  build:
    docker:
      - image: microsoft/aspnetcore-build:2.0
    steps:
      - checkout
      - run: find .
      - run: dotnet restore
      - run: dotnet build
      - run: dotnet test --no-build [テストディレクトリ]

Start building

CIが回って、 SUCCESS が表示されればOKです。 f:id:danker512:20180415171448p:plain

参考:
Building ASP.NET Core apps on CircleCI // Maartens Notebook
CircleCI を使って C# で書いた AWS Lambda Function のデプロイを自動化する - しばやん雑記
Linux における .NET Core の前提条件 | Microsoft Docs
circle.ymlの書き方 - 冷やしブログはじめました

【C#】xUnitを使用した単体テスト

環境

.NET コマンド ライン ツール (2.1.2)

Product Information:
 Version:            2.1.2

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.12
 OS Platform: Darwin
 RID:         osx.10.12-x64

Microsoft .NET Core Shared Framework Host
  Version  : 2.0.3

ファイル構成

|--PrimeService
|  |--PrimeService.cs
|  |--PrimeService.csproj
|--PrimeService.Tests
|  |--PrimeService.Tests.csproj
|  |--PrimeService_IsPrimeShould.cs
|--TDD.sln

PrimeService_IsPrimeShould.cs

using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
        public class PrimeService_IsPrimeShould
    {
        private readonly PrimeService _primeService;

        public PrimeService_IsPrimeShould()
        {
            _primeService = new PrimeService();
        }

        [Fact]
        public void ReturnFalseGivenValueOf1()
        {
            var result = _primeService.IsPrime(1);

            Assert.False(result, "1 should not be prime");
        }
    }
}

PrimeService.cs

using System;

namespace Prime.Services
{
    public class PrimeService
    {
            public bool IsPrime(int candidate)
            {
                if (candidate == 1)
                {
                        return false;
                }
                throw new NotImplementedException("Please create a test first");
            }

    }
}

出力

$ cd PrimeService.Tests/
$ dotnet test

テスト実行
Microsoft (R) Test Execution Command Line Tool Version 15.5.0
Copyright (c) Microsoft Corporation.  All rights reserved.

テスト実行を開始しています。お待ちください...
[xUnit.net 00:00:00.4434140]   Discovering: PrimeService.Tests
[xUnit.net 00:00:00.5006950]   Discovered:  PrimeService.Tests
[xUnit.net 00:00:00.5068960]   Starting:    PrimeService.Tests
[xUnit.net 00:00:00.6747760]   Finished:    PrimeService.Tests

テストの合計数: 1。成功: 1。失敗:0。スキップ: 0。
テストの実行に成功しました。
テスト実行時間: 1.5004 秒

参考:
dotnet テストと xUnit を使用した .NET Core での単体テスト C# コード | Microsoft Docs

日時/時間の減算

日時(DateTime構造体)は日付同士の加算はできないが、減算はできる。
時間(TimeSpan構造体)は加減算が可能。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.IO;
  6 
  7 namespace Program
  8 {
  9     class Program {
 10         static void Main(string[] arg) {
 11             var past = new DateTime(2018, 3, 20);
 12             var now = DateTime.Now;
 13 
 14             var sub = now - past;
 15             var sub2 = now.Subtract(past);
 16 
 17             // var add = now + past;
 18             // Operator `+' cannot be applied to operands of type `System.DateTime' and `System.DateTime'
 19 
 20             Console.WriteLine("sub; {0}", sub);
 21             Console.WriteLine("sub2: {0}", sub2);
 22 
 23             // 10days, 5hours, 6minutes and 1seconds
 24             var tSpan = new TimeSpan(10, 5, 6, 1);
 25 
 26             var tSub = now - tSpan;
 27             var tSub2 = now.Subtract(tSpan);
 28 
 29             var tAdd = now + tSpan;
 30             var tAdd2 = now.Add(tSpan);
 31 
 32             Console.WriteLine("tSub: {0}", tSub);
 33             Console.WriteLine("tSub2: {0}", tSub2);
 34 
 35             Console.WriteLine("tAdd: {0}", tAdd);
 36             Console.WriteLine("tAdd2: {0}", tAdd2);
 37         }
 38     }
 39 }
sub; 1.16:09:16.2632200
sub2: 1.16:09:16.2632200
tSub: 2018/03/11 11:03:15
tSub2: 2018/03/11 11:03:15
tAdd: 2018/03/31 21:15:17
tAdd2: 2018/03/31 21:15:17