2021年を始める

とても久しぶりに戻ってきました。

今回書く内容は、2020年の振り返りと2021年に向けてのパッションです。

2020年の振り返り

後輩が出来たこと。

自分にとって、この一年で最も成長した要因はこれ。 自分からみて業務を一通り「こなせる」ことと、他者に理解できるように具体的かつ「包括的に」説明できることは全く異なる。 異なる要素となるのは、なぜの部分。

初めたての頃は気になってたかもしれないが、仕事というのは良くも悪くも慣れで何とかなってしまう部分も少なくない。 しかし、後輩に改めて一から伝えようとすると、言語化できない部分、つまりなぜやるのかを理解していない箇所を自覚させられることに気づいた。

恥ずかしい話、意気揚々とオンボーディングを始めていて、一発目の資料を開いて、その一発目の説明が出来なかったことは、私のドメインについての理解のなさ(興味のなさに近い)を猛烈に反省することになり、 明日返答させてくれ!とその場を見逃してもらった思い出は消えることはないだろう。

OJTコーチン

(長いですよ) 余談だが、2019年に個人的にコーチングを学んでいたことがあり、奇しくも後輩との接し方に反映することが出来たように感じた。

メンターやトレーナーといった言葉は定義があいまいになりがちで、OJTの面倒見役といえばトレーナーだろう。 トレーナーは技術のプロフェッショナルであり、その技術についてはトレーニーに過不足なくフィードバックを行えるのが望ましいとされる。 ではメンターとはなんだろうか。一般的にコーチングを知らない人にとって、このメンターとしての役割をすぐにイメージするのは難しいのではないかと思う。 さくっと調べたところ、「精神的なサポート」を担う人をそう呼ぶようだ。精神的なサポートとは何か。

所説ある中で、コーチングのクライアントとコーチの関係性から見てみたい。コーチングでいうコーチの役割はズバリ「100%クライアントを応援する」人の事を指す。 100%とはどういう意味かというと、自分の利益を入れないということ。お金を取ってはダメとかそういう意味では無くて、手を抜かないということ。(世の中にはマッチポンプ的手法で、つなぎとめるような行為が多すぎる)

また同時にクライアントもコーチと同様、やりとりする内容について「本気で達成したいと思っている」ことが前提になっている。 全力で達成したい人を全力で応援するから、壁を突破するんだよってことですね。

とにかく、私がコーチとしてあるべき姿を意識した瞬間に足りないものがたくさん気づけて、このままではヤバいとなったわけです。

私にとっては成長のトリガーは、興味関心のあったコーチングがきっかけでしたが、人によって何を重んじるかは異なるので、ベクトルが違う経験・機会が多い環境ほど、こういった現象は起きるのではないかと思いました。

運動不足

コロナでリモートワークが義務付けられた後、家で始まり家で終わるというライフサイクルから抜け出せなくなり、気づいたら運動量が全然足りてませんでした。

脳や体の専門医などから話を聞くと、強い肉体には強い精神が宿る は正しいとのこと。心と体はつながっているのでおろそかにしてはいけなかったのだ。 つまり運動不足で肉体が弱まる中、仕事はハードワークになっていったので、気づいたらイエローラインを超えてましたとさ。あと一歩のところまで自分を追い詰めてました。

ま、事なきを得たんだけれども、頭のネジ1本はどっか行っちゃった笑

仕事について考え方が変わったこと

雑な言い方だけど、私のいただいているお給料って、どこから生まれてきたものなの?っていう意識ができた。

持株会を通じて、IRに関する財務諸表の知識を学んでみたり、株主の存在を意識する機会が増えたね。

ビジネスマンとして生きる

今日のITのエンジニアに求められている要素って、今までにない技術を生み出せる(0から1)ような基礎研究できるエンジニア というより、 基本は必要十分できて、ビジネスの目標を達成するために求められるサービスの構築や運営を 可能な限り低コストで実現させるエンジニアなんじゃないか。

ビジネスの規模によって具体的な要素はダイナミックに変化するよね。Twitter社だってスタートアップ時はRailsで、軌道に乗った後 React/Scala に変わったのを見ても、その時に求められる技術や知見は全く違うと言える。

なんにせよ、技術そのものの価値はあまり高くない。セールストーク風に言い換えると、〇〇が出来ます => 世の中にできる人はいっぱいいる。 なぜ〇〇が必要なのかを説明できる => ビジネスの目標と照らし合わせて理由を説明できる人は少ない。 このような図式が、働いてると見えてきたわけです。後者は基礎の理解と経験が必要ですね。コードをばりばり書く段階から、少しずつ視野を広げていって目指したい状態ではあります。

35年定年説とかぶっちゃけ嘘。事業に貢献できる人はいくつであっても引手あまたです。

2021年に向けて

新たな目標ができたこと

新たな目標が出来ました 出来たっていうより、発見したっていうニュアンスかな。

スパン的には4~5年くらい準備期間が必要でそこからが勝負って感じの内容かな

達成するためには思いっきり自分を変えなくちゃいけない。でもやりたい事だからやる。ありがたいね、こういう気持ちって。

コーチングでは基本言わないが正しいので)言えませんが、達成したら書かせていただきます。

肉体を大事にする

ほんと、肉体は資本だよ! もし一時間の時間が出来たときに選択肢があるとするなら、肉体の強化を積極的に選んでいく。(今まではやれ勉強やら動画、ゲームの比率高かった)

まっちょ目指すよ!! イケメンになって彼女もできるかもしれないね!(笑

用語の整理

  • メンター: メンタリングを行う人。(正直良く分かってない)
    • 目的地の設定は、メンターが属する組織が設定する。
  • コーチ: コーチングを行う人。語源は馬車。クライアントを目的地まで送り出す人。
    • 目的地の設定はクライアントが設定する。
  • トレーナー: トレーニングを指導する人。
    • 訓練内容があらかじめ存在し、トレーニーの修了を支援する。
    • こうみると今日の日本の学校教員はほとんどトレーナーに近い印象を受けました。

チームで物事を進める

本日の学び

チームで物事を進める場合、リーダーが気にする点とは?

  1. 期限までに成果を出す
  2. メンバーが円滑に作業できる状況を作る
  3. 遅れると分かった時点で、期限を引き延ばす

この3点が大切だと気づいた。

1, 2 は連動していて、リーダーの視点からみて、見通しがつく範囲において、ある地点におけるプロジェクトの状態を設定しておき、 その状態になるためには、各メンバーがどのような作業をしていて、どのような準備が必要かを逆算していく。

各メンバーから見た場合、常にやるべきタスクが存在していて、タスクが終了するまでに次のタスクが用意されていれば、円滑に進められる。

そして、一定期間ごとに各メンバーが意図した作業が出来ているかを確認し、遅れや問題が発生していれば修正を行う。

定例ミーティングはそのための確認作業であり、想定通りならサクッと終わらせるくらいが良いのではないだろうか。 何か想定外の事態が起きた場合のみ、関係者同士で対策を行えばいい。

そうしてプロジェクトが常にあるべき状態になるよう、適切にチューニングを行うのがリーダーの役割(の1つ)である。

生産性とは何か? - p.1

今回は考察シリーズです new!

テーマは「生産性とは何か?」

生産性という言葉は、色んなイメージが着いてしまっているので、整理してみたいと思います。

定義を見てみましょう。 Wikipediaから引用します。

生産性(せいさんせい、Productivity)とは、経済学で生産活動に対する生産要素(労働・資本など)の寄与度、あるいは、資源から付加価値を産み出す際の効率の程度のことを指す。 一定の資源からどれだけ多くの付加価値を産み出せるかという測定法と、一定の付加価値をどれだけ少ない資源で産み出せるかという測定法がある。

ふーむ。資源から付加価値を生み出す際の効率の程度なのか。

人間で置き換えると、私(あなた)がどれだけ効率良く付加価値を生み出せるかっていうことですね。

付加価値という言葉が出てきましたね。

Wikipediaから引用します。

付加価値(ふかかち、英: added value)とは、 1. 生産によって新たに加えられた価値。総生産額から原材料費・燃料費・減価償却費などを差し引いた額。減価償却費を差し引かない付加価値を粗付加価値、減価償却費を差し引く付加価値を純付加価値という。 2. 通俗的には「特定の人・場所・施設や何かの商品・サービスなどに付け加えられた独自の価値」という意味で用いられることがある。

なるほど。

サラリーマンの場合、生産性の指標とは、月給があるので、貰った金額以上にどれだけお勤め先の企業に貢献できたかと言えますね。

ということは、投資した価値がより大きくなって帰ってきた場合は生産性が高く、その逆は低いと。

いわゆる投資みたいな概念でしたね(笑)

労働者の立場で、生産性が高いということは、短い時間で高い成果を上げることですね。

我々人間ですから、お仕事とプライベートのバランスが成り立ってQoLが上がるわけです。

つまりお仕事をするときは、長期的にみて高い生産性が発揮できる環境・内容を選んだ方が良いわけです。

(余談ですが、私が企業選びをした際は、私にとって働きやすい環境かどうか、を第一優先にして、給料はまったく見ていませんでした笑)

次回は、より高い生産性を発揮するためには何が重要なのかについて考察してみたいと思います。

ここまでお読みくださり、ありがとうございます。

既存機能の信頼性を担保してから変更を行う

本日の学び

開発フローにおけるテスト観点について、新たな学びがあった。

今回はやや複雑な事情になるため、整理しながらまとめていく。

開発アイテムが既存の機能の拡張を行う

すでにある機能に手を加えて新規機能を追加した。

既存機能は、データの操作が複雑化されていて、新たな処理を加えた場合の影響範囲が広いため、

既存処理を改修していく形式で(スケジュールの都合上)行っていった。

一部の機能改善

開発 > テスト > レビュー を経て、トピックに取り込まれ、ステージング環境で再試験したところ、バグが発覚した。

バグの原因は改修範囲内のコードだったことが判明し、無事修正が行われた。

なぜ単体での開発時に気がつかなかったのか。

原因は2点。

  1. DBのデータセットが正しかった。
  2. 既存機能はDBのデータセットが正しい場合のみを想定していた。

正常系のみ考慮

つまりステージング環境のDBは本番では想定していないようなデータセットになっていて、

そこが起点で既存機能に含まれているバグをあぶり出す形になった。

当然、このまま本番へデプロイしていたら普通に動いていただろう。(ローカルで正しいデータセットなら動いていたため)

ある意味仕方がなかった話ではあったが、教訓と対策を得ることができた。

既存機能(ブラックボックス)はバグを内包している可能性が常にあり、今うまく動いている前提条件をきちんと明示的にしておかないと、(メンバーが入れ替わった際など)後々バグを生みやすくなる、ということ。

これは内部仕様書やユニットテストでカバーしたく、今後の開発フローにおけるレビューでチェックしていきたい。

また実装するフェーズにおいて、すでに動いている部分を全面的に信頼するのではなく、

うまく動いているように見えている可能性も考慮し、データフローに関する精読・(欠けていれば)ユニットテストも追加し、既存機能の信頼性を担保してから、改修を進めていくことにする。

開発プロセスについて

本日の学び

機能実装における開発プロセスにおいて

仕様策定 -> テスト観点のレビュー -> 実装

実装 -> テスト実施 -> 仕様を満たしていれば機能ブランチに取り組む。

開発サイクル

基本的には上記のフローを踏むことによって、「仕様通りかどうか」を確認しつつ、「バグまたはデグレが起きるかどうか」の早期発見に繋がる。

ただし、例外の流れが存在していて 「仕様が変更される」ケースに対してのフローを想定していなかったため、 テスト観点と実装において、「仕様通りかどうか」にブレが生じてしまった。

実装・テスト・その他のフロー、いずれのフェーズにおいても「仕様の変更」が必要になった時点で、このサイクルを一旦停止し、 フローの最初に戻って行うべきだと考える。

開発サイクル

しかし、確実ではあるが現実的なやり方ではない。 なので、1週間で1サイクルなど期間を定義し、改善要求を蓄積させ、次のサイクルから反映させるのが良いのではないかと考える。

開発サイクル

こうすることで、要件に変更がない機能は取り込まれ、かつ仕様変更が行われた部分については適切に扱うことが可能になる。 当たり前の話かもしれないが、スケジュールの都合や緊急度によっては、臨時対応などがあり、このフローから漏れてしまうケースがあり、あとからバグが出たりする。

普段行う作業は、なるべく負担のないフレームであって、しっかりと高い品質を維持できるようなやり方を模索していきたい。

DOMとか仮想DOMとか聞くけど、一体なんなのか

Reactを勉強していると仮想DOMや差分レンダリングなどのキーワードを目にしますが、いまいちパッと理解できなかったので、そのための覚書です。

トピック一覧

  • DOMとは?
  • JavaScript とは
  • Virtual DOM (仮想DOM) とは?
  • React Component とは?

DOMとは?

www.doraneko.org

DOMはインターフェースであり、Html, Xmlをどのように操作するのかを定義したものである。

逆に、バイナリの仕様やデータ構造のセットはDOMではない点が分かる。

つまり、ブラウザ毎に、内部の仕様は異なるが、DOMに準拠していれば、Htmlを同じように表示、操作できることを意味する。

補足: DOMは、XML文書やHTML文書を処理するために使ってよいインターフェイスを指定する。
これらのインターフェイスが抽象概念である -- C++ の「抽象的ベースクラス」によく似て、ある文書のアプリケーションの内部的表現にアクセスし、操作するための方法を指定する手段である -- ことを認識することは重要である。
インターフェイスは、特定の具体的な実装を含意しない。DOMアプリケーションはそれぞれ、この仕様書に示されたインターフェイスがサポートされている限り、任意の便利な表現で文書を維持しても自由である。

JavaScript とは?

developer.mozilla.org

ブラウザ環境上で動く、インタープリターなスクリプト言語である。 ブラウザはDOM (Document Object Model) APIを用意し、JavaScriptはこれを用いてコンテンツの更新などを行う。

ドキュメントオブジェクトモデル (DOM) - Web API | MDN

DOMはウェブページを表す HTML のように — 文書の構造をメモリ内に表現することで、ウェブページとスクリプトプログラミング言語を接続するものです。

ウェブページとスクリプトプログラミング言語を接続する ここが重要なポイントだと思います。

JavaScript は何をするのか の部分で、 ブラウザは入力としてHtml, Css, JavaScript を受け取り、先ずHtml, Cssを処理し、Webページを出力します。 そして、JavaScriptエンジンによってJavaScriptは実行されます。 DOM APIを通じて、動的にHtml, Css を更新します。

Web App を構築する上での基本的な流れが掴めます。

Virtual DOM (仮想DOM)とは?

Virtual DOM (以降はVDOM)を 以下のサイトを参考に考察します。

reactjs.org

ブラウザがHtml, Cssを入力し、Webページを出力する流れをみました。 Webページの内容(タグや属性など)をJavaScriptから操作する意味では同じですが、 JavaScript内でHtml, Cssライクなオブジェクトを構築し、それを最終的にWebページに反映させる点が、従来と異なります。 イメージとしてはJavaScript言語上でUIの要素群があり(コンポーネントと呼ばれる)、それがHtml, Cssに翻訳されてWebページに反映される感じでしょうか。

UIコンポーネントのデータ構造とブラウザとのインターフェースを設計できれば、React, Vue などのフレームワークとまでは言わなくとも、 簡単なフレームワークを作れるということです。

React Component とは?

VDOMの一種という解釈が妥当だと思います。 React は UI コンポーネントと、fiber と呼ばれる内部オブジェクトを VDOMと見なすことができます。 ここはまた、Reactとして別記事で詳しく紹介したいと思います!

Node.js ES2015 require の働きについて

ES2015によるモジュールの扱い方をまとめてみました。

  • モジュールのインポートは require
  • モジュールのエクスポートは module.exports

それぞれ、どのような性質があるのか見ていきましょう。

require の働き

require は引数による挙動が複数あるため、一つ一つ理解しましょう。 まず、パッケージがインストールされる経緯は2通りあります

  1. npm install 経由(./node_modules/ へ)
  2. 自作ライブラリ (任意のディレクトリへ)

npm install 経由で入れた場合

通常のインストールであればpackage.jsonにパッケージ情報が追加されます。

lodashをインストールした package.jsonの例

{
  "name": "example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.11"
  }
}

dependencies に追加されたことがわかります。 では、lodashの package.jsonはどうでしょうか

{
  ...省略
  "main": "lodash.js",
  "name": "lodash",
  "version": "4.17.11"
}

name がパッケージ名, main がインポートされる js ファイルです。

上記の例だとrequire('lodash') をすると、./node_modules/lodash/lodash.js ファイルがインポートされます。

もし、./node_modules 以下にモジュールが見つからない場合は、ルートディレクトリに登りながら検索が行われます。

  • /hoge/ry/project/node_modules/lodash.js
  • /hoge/ry/node_modules/lodash.js
  • ...省略
  • /node_modules/lodash.js // ここで検索が終わる

なので一つ上のディレクトリにパッケージが含まれていた場合は npm install していなくても利用できます。

自作ライブラリの場合

require の引数に 自作ライブラリへの相対パスを渡せばインポートできます。

また、あるパッケージからの相対パスを用いたインポートも可能です。

├── main.js
├── lib
|  └── helloWorld.js 
└── node_modules
   └── lodash

上記のディレクトリ構成で main.js から helloWorld.js を呼び出す方法

  1. require('./lib/helloWorld')
  2. require('lodash/../../lib/helloWorld') // 使わないと思うけど
まとめると

引数に渡す情報で挙動が異なる

  • require('module_name')
    • /hoge/ry/project/node_modules/module_name.js // から探す。 ない場合はディレクトリが上がっていく。 ルートディレクトリで止まる。
    • /hoge/ry/node_modules/module_name.js
    • ...
    • /node_modules/module_name.js // stop
  • require('path/to/file')
  • require('example_module/path/to/file')
    • example_module のディレクトリを基準にして、ファイルを探す

とあるフォルダーをモジュール化するには

モジュールとして成り立つためには、モジュール化するディレクトリに package.json を作成する。 package.json に追加する項目は2つ

{
    "name" : "some-library",
    "main" : "./lib/some-library.js"
}

これだけです。簡単ですね!

あとは require で読み込むだけ。

module については後日追加