最近読んだ本

ここ数ヶ月で読んだ本の感想です。 わりと技術書ではない本が多い。子供を寝かしつける時間に読んでるのだけど、薄暗い環境ではバックライトのついているKindleが大変便利。Kindleで出てない本はあまり読めない。

人を動かす 完全版

人を動かす 完全版

自己啓発本の元祖みたいな本で、原著は1937年くらいに書かれていて古い。SOFT SKILLSという本で紹介されていて読んだ。基本的に人間は自分の利益を一番に考えている、ということを前提に、他人の利益になることをあえてやっていくと、いろんなことがうまくいくよって話。いくつかのプラクティスに合わせて、具体的なエピソードがたくさん紹介されていておもしろい。著者は自分で伝記を書くくらいリンカーンが好きで、リンカーンまじすげーって気持ちにもなれる。

モチベーション3.0 持続する「やる気!」をいかに引き出すか (講談社+α文庫)

モチベーション3.0 持続する「やる気!」をいかに引き出すか (講談社+α文庫)

2009年くらいの本で、その当時よく話題になっていたのを思い出した。褒められたり罰せられたりするモチベーションよりも、自分が心の底からやりたいというモチベーション( = 内発的動機)の方がより創造的な成果を継続して出せるぞというような話。技術をマスターするには、何年もの間、継続して取り組む力が必要だから内発的動機がめちゃ大事って話があって、子育てとかで気をつけようって思った。

ビジョナリー・カンパニー ― 時代を超える生存の原則

ビジョナリー・カンパニー ― 時代を超える生存の原則

別の記事で感想を書いた。

NETFLIXの最強人事戦略 自由と責任の文化を築く

NETFLIXの最強人事戦略 自由と責任の文化を築く

結構前に読んだので記憶が曖昧。現在の事業に適した人を採用して、方向性が合わなくなった人には転職をおすすめするってのを、割とドライにやってるって話題が興味深かった。Netflixとしては検索機能が大事だと思っているときに、めっちゃFacebook連携をやりたい人がいたんだけど、SNSやりたければFacebookに転職しても良いのよって声かけて、最終的には出て行くことになったとか。なんなら転職のサポートをして推薦文を書いたりするらしい。基本理念を大事にして、その理念に賛同するメンバーを集めたり育てたりするという、ビジョナリーカンパニーのイメージにも近い感じがした。

イシューからはじめよ―知的生産の「シンプルな本質」

イシューからはじめよ―知的生産の「シンプルな本質」

結構まわりの人が話題にしていることが多い気がしてみて読んでみた。答えを出したいイシューに対して決められた期間で答えを出すためにどのような、考え方、取り組み方をすれば良いかについてすごく綺麗にまとめられていた。自ら問題を定義するような仕事をしている、(著者もそうであったように)研修者の方なんかにはとくに役立ちそうに感じた。そうでない仕事をしていても、やってきた課題を鵜呑みにせずにまずイシューを見つけるところから始めるのは良さそうに思う。自分がいま何を学ぶべきかをよく考えるけど、そういう場面でも学んだ結果として、自分にとってのどんなイシューに答えを出せるかは意識しても良さそうと思った。

逆境に弱い人、逆境に強い人

逆境に弱い人、逆境に強い人

自分は逆境に弱いなーってずっと思っていたところ、TwitterのTLにこの本のURLが流れてきてためしに読んでみた。大変なことでも、人生長いので大局的に見るとどうにでもなるよとか、普段からうじうじしてるとそれだけで体力を使うから、いざというときに力が出ないよとか、多量のエピソードとアドバイスがつらつら書かれている感じのスタイル。論理的には断言できなさそうなことも、どんどん断言されているので、読んでいてドキドキする。元気のない人を元気づけようとしている感じの本なのでそういう感じなのだと思う。とはいえ、いろんな資料への参照もあってしっかりした感じだし、ちょっと見方を変えて気楽に元気にやっていこって気持ちにはなれた。

振り返ると結構いろいろ読んでるけど、計画性はなく雑に読んでいる状態。いい本読みたい。

ビジョナリー・カンパニーを読んだ

ビジョナリー・カンパニー ― 時代を超える生存の原則

ビジョナリー・カンパニー ― 時代を超える生存の原則

普通に有名な本で、モチベーション3.0という本を眺めていたらおすすめされていて機運が高まり読むことにした。

著者は、アメリカの様々な業種の企業のCEOにアンケートを取り、そこから浮かび上がってきた卓越した18の企業と、それらに対応する比較対象の企業を18選び、その18組の企業について業績や基本理念、歴史といった様々な視点での調査を行っている。6年もの長い調査の結果、浮かび上がってきたビジョナリーな企業に共通する性質について紹介したのがこの本だ。

この本の原著は1994年に発売されているので、時代背景の違いは多少感じるものの、取り上げられているトピックについては企業で働いている僕のような個人が現代も共感できるものが多かった。ビジョナリー・カンパニーとして取り上げられている企業には、テクノロジー系だとヒューレット・パッカード、ソニー、IBMなどがなどがあった。

ビジョナリー・カンパニーを作り上げるポイントが本書ではいくつか挙げられているけれども、最も大事とされていて、自分としても印象に残ったのは「基本理念を維持し、進歩を促す」という慣行についてだ。つまり、企業の目的や価値観からなる基本理念を土台にすることで企業を継続し、それと同時に絶えず変化して進歩していくことで生き残るということだ。これらをどちらも諦めずに行えているかどうかがビジョナリーであるかの鍵となっている書かれている。太極図が挿絵に書かれていてそういう感じ。

言うのは簡単だけど、実際にやっていくのは、めちゃくちゃ難しいよねとは思う。まず基本理念を浮かび上がらせるのが大変だし、それを従業員が常に意識し続けられるようにするのも大変だし、常に進歩するってのもいろいろあって簡単ではないし。本書でもめちゃくちゃ難しいのでありとあらゆる工夫をし続けてがんばって維持するんじゃ、と書かれている....。18の企業がどういった工夫をしてきたかについては何章もかけて紹介されている。

工夫のなかでおもしろかったのは後継者を育てることの重要性について述べられているところだ。本書のビジョナリー・カンパニーの定義では企業が長く続いている(50年近く)ことが要求されており、経営者が代替わりしようとも、世代を超えて組織自体が繁栄し続けている企業に注目している。人間はいつか死ぬので、一人のカリスマがいるだけでは、組織が繁栄し続けることはできない。そのことに気づいて、数十年先の会社がどうなっていくかについて考えて、十分な時間をかけて基本理念を完璧に理解している後継者を育てた企業が長く継続しているのだ。自分としてはそういう時間スケールで考えたことがなかったので興味深かった。

本書では、企業のいろんな性質について、うまくいっている企業と、そうでない企業の具体例による比較がかなりの分量ある。それを読んでいると、自分の働いている環境ではここはうまくいっているな、ここはもう少しだなと、都度思い返すことになって、ある意味真剣に読んでいくことができた。気持ち的な負荷はまぁまぁあるので、疲れているときには読みづらかった。

企業はこうあるべきという大正解は別にないと思うものの、自分の中でうまくいってる企業の一般的なイメージが膨らんだので、読んでみてよかった。

grpc-gateway と使われてるProtocolBuffer周辺技術メモ

grpc-gatewayはHTTP2+ProtocolBuffer をプロトコルに用いるgRPCのサービスを、HTTP/1.1のRESTfulな JSON APIとして利用できるようにするリバースプロキシを生成してくれるツールだ。

厳密にはProtocolBuffersを処理するコマンドであるprotocのプラグインとして動作し、protocに読み込んだgRPCのサービス定義をもとにGoで記述されたコードを生成する。生成されたコードはHTTPサーバのハンドラになっていて、net/httpに登録して使えるようになっている。

ハンドラはHTTP/1.1でリクエストを受け取ると、リクエストに含まれるJSONを対応するProtocolBufferのメッセージに変換し、プロキシ先のgRPCサービスのメソッドを呼び出す。このgRPCサービスは、元にしたスキーマが同じであればGo以外の言語で実装されていても良い。そしてメソッドの呼び出し結果のProtocolBufferメッセージをJSONに変換してレスポンスを作る。

gRPCは利用したいが、既存のシステムから簡単に利用するためにREST APIの口を残したいだとか、管理用のAPI Explorer的なものを作るときにWebブラウザから直接利用できるREST APIがほしいだとか、そういった際に便利なツールである。

くわしくは作者であるyuguiさんの紹介記事やリポジトリのREADMEを読むとわかりやすい。

使い方などは上記の記事を読めば十分なので、この記事ではgrpc-gatewayを利用する過程で僕が学んだ gRPCやProtocolBufferに関する知見をまとめてみようと思う。メモ的なものだけど、役立つ資料へのポインタも貼っておくので何かの参考になればうれしい。

protocとプラグインによるコード生成

grpc-gatewayを利用する際には以下のようなコマンドを実行する。このコマンドの結果としてリバースプロキシのコードが生成される。

protoc -I... -I... --grpc-gateway_out=. path/to/your_service.proto

protocでは、--grpc-gateway_out のようなオプションを指定することでProtocolBufferのスキーマを元にしたコードの生成機能を利用できる。このオプションはプラグインの読み込みの仕組みになっていて、例えば --hogehoge_outのようにオプションをすると、protocがprotoc-gen-hogehogeという名前のコマンドが利用されるようになっている。

プラグインは標準入力からパース済みのProtocolBufferのスキーマ情報を受け取り、その情報を元に何らかの処理を行って、結果として生成するファイルの名前やその内容を標準出力に出力するというインタフェースになっている。標準入出力でやりとりされるデータがProtocolBufferのバイナリになっているのがおもしろい。

詳しい仕組みについては、yuguiさんによる以下の記事が参考になる。

ProtocolBuffer 定義ファイルのoption

grpc-gateway を利用する時使うProtocolBufferのスキーマは、例えば以下のようになる。

syntax = "proto3";
package articles;

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

// 省略

service ArticlesService {
    rpc Post(PostRequest) returns (PostResponse) {
        option (google.api.http) = {
            post: "/articles/post"
            body: "*"
        };
    };
    rpc Recent(google.protobuf.Empty) returns (RecentResponse) {
        option (google.api.http) = {
            get: "/articles/recent"
        };
    };
}

注目すべきは、optionという文法でメソッド定義に対応するURLのパス情報が記述されている部分だ。

ProtocolBufferのスキーマは基本的にはメッセージやサービス定義を記述する仕組みではあるが、grpc-gatewayのような生成ツールから利用する固有の情報を定義に追加して埋め込むこともできる。その埋め込みのための記法がoptionで、この例のようにメソッド追加の情報を記述する以外にも、幾つかの文法要素に情報を埋め込むことができる。

メソッドに対してoptionに指定できる属性は、MethodOptions型としてあらかじめ定義されいるが、独自にoptionを定義して属性を追加することもできる。option (google.api.http) = ...のような表記はgoogle.apiパッケージにおいて拡張されたhttp optionを設定するといった意味になる。

この話題についてもyuguiさんの記事が参考になりおすすめだ。

ProtocolBuffer と JSONの変換

ProtocolBufferの仕様には、ProtocolBufferとJSONのマッピングが含まれており、ProtocolBufferとJSONの相互変換は基本的に可能である。各言語のProtocolBufferのライブラリにもJSONへの変換機能が含まれていたりする。

golang/protobufを使ってGo向けに生成したProtocolBufferのメッセージ構造体にはJSONへの変換のためのタグが指定されているので、Goの標準のjsonライブラリを使えばProtocolBufferとJSONの相互変換は可能である。ただ一部のデータ型は標準のjsonライブラリを利用するだけでは変換が難しいため、jsonpbというより完全な相互変換が行えるライブラリも存在する。

grpc-gatewayの内部では、ProtocolBufferとJSONの相互変換を行っている。デフォルトではjsonpbを利用するようになっているが、より高速な標準のjsonライブラリを利用する設定にもできる。

このあたりの話題については以下の記事でも詳しい。

感想

grpc-gatewayはツールとして便利なだけでなく、ProtocolBuffer周辺の様々な技術が利用されているので、自然と知識が得られてよかった。あとyuguiさんのgRPCやProtocolBufferに関する資料がとにかく充実していて、技術的背景を理解できるようになって良かったので、一通り読むことをおすすめしたい。

gRPC周辺技術にはそこそこ慣れてきたのと、情報ソースもわかってきたので、ある程度実用的なものを作ってみるのが次のステップのようには思うので少し考えてみる。

gRPCのロードバランシング

先日の記事から引き続きgRPCについて勉強してる。

gRPCのサーバをプロダクトで利用する場合に気になるのが、ロードバランシングをどういう風にやったら良いのかということで、その部分について調べてみた。

TL;DR: gRPC Load Balancing を読めばだいたいわかる

gRPCのロードバランシングのポイントとしては、gRPCが基本的にはHTTP2上に構築された仕組みである*1ことに注意して考えると良さそうだった。

プロキシ によるロードバランシング

まず考えられるのは、gRPCのサーバとクライアントの間にプロキシを設置してロードバランシングを行う方法だ。

よくあるHTTP/1.1の世界で考えると、複数のWebアプリケーションサーバの前段にnginxのようなリバースプロキシを設置してロードバランシングする方法になる。

gRPCはHTTP/2を利用するので、この方法の場合リバースプロキシもHTTP/2を理解できる必要がある。これを実際に行うには、例えば、先月リリースされたNginxのgRPCサポート機能が利用できる。一方、AWSの環境でよく利用されるALBは、プロキシの後ろ側の通信がHTTP/1.1になるため利用できない(参考: gRPC アプリケーションを AWS で動かすときの注意点 ) 。

上記の方法ではL7でのプロキシを用いていたが、L4のプロキシでロードバランシングする方法も考えられる。TCPのコネクションレベルでロードバランシングを行うのでL7のプロトコルがHTTP/2でも影響をうけない。これを実際に行うには haproxyを利用したり、AWSのNLBが利用できる。

気をつけないと行けないのは、HTTP/2の利点を活かすためgRPCのクライアントがなるべく一つのコネクションを使い続けるような仕組みになっていることだ。L4のプロキシによるロードバランシングが働くのはTCPのコネクションを張るときなので、そのコネクションを利用している限りは同じサーバを利用し続けることになる。

例えば、Webアプリケーションが1リクエスト処理するごとにgRPCのコネクションを毎回張るような実装であれば、L4プロキシによるロードバランシングでも十分よく機能するだろう。一方、サーバ起動時に一度だけつくったgRPCクライアントを使い続ける場合、意図せず同じ一つのgRPCサーバとのみ通信をすることになるかもしれない。

クライアントサイド ロードバランシング

ロードバランシングというと前述のようなプロキシサーバを用いた形式を考えてしまうのだけれども(僕は)、gRPC界隈ではクライアントサイドでのプロキシの仕組みも充実している。

クライアントサイドロードバランシングは、gRPCのクライアントがいくつかの接続先のサーバを知っており、gRPCメソッドの呼び出し時などに適宜、利用するサーバを切り替えることでロードバランシングをする方法だ。プロキシサーバを中継しないため、高速に動作するが、gRPCクライアントの実装が複雑になる。実際クライアントサイドバランシングは、どのgRPCクライアントにも実装されているわけではなく、少なくともGoとJavaには実装があるような状態だった。

GoのgRPCのクライアントライブラリにはround robin 方式のロードバランサー(grpc.RoundRobin)だけが実装されている。この grpc.RoundRobin は接続先のサーバの名前解決をする naming.Resolver を受け取るようになっている。

naming.Resolverの実装としては、DNSを用いたものが付属していて、DNSにホスト名を問い合わせることで幾つかのサーバのアドレスを取得して、gRPCの接続先のサーバの候補に加えるという仕組みになっている。naming.Resolverはワンショットで動作するのではなく、定期的に名前解決を実行して、サーバの候補を更新する。naming.Resolverの実装はDNSを用いる必要はなく、例えばEtcdにサーバの一覧を問い合わせるといった実装も可能になっている。

このような名前解決の仕組みだけでなく、サーバ側の負荷をフィードバックする仕組みなど、様々なロードバランサーの機能をクライアントライブラリごとに実装するのは大変なので、その部分だけを別のシステムに移譲する、extenal load balancingという仕組みを利用することもできる。gRPCのロードバランシングのコンセプトまとめたドキュメントには、external load balancerについても説明されている。おもしろい仕組みだけどもあまり実装はないようである(僕は grpclb っていうのだけ見つけることができた)。

結局どうすればいいのか

gRPC Load Balancing という記事の最下部にユースケース別のロードバランシングのおすすめ表があるので、これを参考にしまくると良い。Kubernetesを利用する場合は deeeetさんの
Kubernetes上でgRPCサービスを動かす | SOTA がめちゃくちゃ参考になりそうだった。

自分としては運用のイメージのしやすさとしては、nginxのgRPCサポート機能を使うかL4のロードバランサーを気をつけて利用するのが良さそうには思った。

gRPCの利用シーンとしてはマイクロサービスのインターフェースがやはりいちばん考えられるので、クライアントサイドロードバランシングをうまく使いこなせれば、より効率的な構成にできそうには思うが、サーバ構成をアプリケーションからみて動的に解決できる状態にまずする必要がありそうで、まぁ準備が大変そうだなという感想。

おまけ

クライアントサイドロードバランシングの雰囲気をつかむために例になるようなgRPCのサーバとクライントを実装してみた。

上述した、Goに付属のgrpc.RoundRobinを用いている。これもGoに付属しているDNSを用いたnaming.Resolverを動作させようとすると、DNSの設定を行う必要があって大変なので、初期値として与えた固定のgRPCサーバの列を返すnaming.Resolver を雑に実装して試せるようにしている。

github.com

次のステップ

たぶん grpc-gatewayの雰囲気をみておくと良い。grpcのクライアントの感じとかも調べると良さそう。

*1:正確にはトランスポート層は別のプロトコルを利用することもできる

gRPCを学んでいる

マイクロサービスや自作ミドルウェアのAPIをメンテナブルにしたいよねっていう文脈で、OpenAPIGraphQLgRPCといった技術が採用されるのを最近よく目にする。

バックエンドを実装しているWebエンジニアとしては、こういう仕組みが整備されつつあるのはありがたい。APIをシステムの外に公開しようとすると、ドキュメンテーション/バリデーション/クライアントの実装など、意外と副次的な作業が必要なので、、汎用化されたツールに頼れるのは助かる。マイクロサービスを用いたアーキテクチャを考えるにあたっても、システム間のアダプタをイメージしやすくなる。

そういう背景で、最近家ではgRPCを調べている。このあとはgRPCについて調べたことのメモや感想のコーナーになっているので、興味があったらどうぞ。

主な情報源

だいたいこのへんを眺めておくと、gRPCの基本については抑えることができる。

試しにコードを書いてみた

自分でprotoを定義して、gRPCのプログラミングを体験してみた。

いくつかの言語でgRPCのサーバ/クライアントを実装してみたかったので、同じメソッドを実装したgrpcサーバをたくさん立てると、勝手に連携して動作するような構成にしてみた。コードはGitHubに置いてある。Dockerを使って試せるようになっているので、make build && make upとすると動いているところが見れる。

github.com

全体を管理するBossプロセスとその元で働くMemberプロセスがいて、以下のような感じで動作する。特に何かの役に立つというモノではない。


  1. Bossプロセスを起動する
  2. いくつかのMemberプロセスを起動する。Memberプロセスは起動したらBossプロセスのJoinメソッド呼び出す、このシステムに参加する
  3. Boss プロセスはしばらくMemberプロセスの参加を待ったあと、Memberプロセスの順序を決める。
  4. Bossプロセスは決めた順番になるように、各Memberプロセスに対して、そのプロセスの次のプロセスを指定するSetNextメソッドを呼び出す。循環するように一番最後のMemberプロセスの次のプロセスは最初のプロセスになるようにしておく
  5. Bossが最初のMemberに対してPokeメソッドを呼び出す。MemberプロセスのPokeメソッドを呼び出すと、そのMember次のMemberのPokeを呼び出すようにしておく
  6. 一度投入されたPokeメソッドの呼び出しは連鎖して無限に呼び出され続ける

本当は、gRPCのサーバとクライアントを10言語で実装してみた結果www みたいな感じでレポートしようとしたけど、似たような実装を繰り返すだけみたいな雰囲気になったので途中で飽きて終わった...。

感想

  • データ型とメソッドのシグニチャのみでRPCのインタフェースを定義できるのが簡潔で良い
    • クエリやPOSTされたメッセージとデータ型との対応をちまちま定義する必要がない
    • RPCのドキュメントとしてみたときも分かりやすい
  • プログラミング言語ごとにprotocで生成されるgRPCサーバの実装モデルがまちまちなので注意する
    • 共通のgRPCサーバ実装というのはなく、各プログラミング言語ごとに丁寧に実装されている(それぞれの言語の実装を眺めるとおもしろい)
    • 実装モデルを理解して利用しないとパフォーマンスの問題が起こるかもしれない(PythonやRubyではGILに注意するとか)
    • PHP ではそもそもサーバの実装がなかったりした
  • プログラミング言語ごとにprotocで生成されるgRPCクライアントの機能がまちまちなので注意する
    • Pythonのクライアントでは非同期にgRPCのメソッド呼び出しをして結果をfutureで得たりできておもしろい
  • 静的型付けのプログラミング言語と相性が良い印象
    • Protocol Bufferで定義したmessage型と、gRPCを実装しているプログラミング言語上の型との間に直接対応があるとわかりやすい

書いてみた中では、Goと相性が良かったように思う。Google文化圏の技術同士だからという感じはある。

次のアクション

ひとまずシンプルなサーバとクライアントを実装しただけなので、もう少し進んだトピックにも取り組んでみる

  • ストリーミング
    • gRPCはストリーミングでメッセージを送受信できるので体験してみる
  • ロードバランシング/冗長化
    • 実際のシステムで利用するにはロードバランシングや冗長化が必要になる。gRPC的には一つのトピックみたいなので調べてみる
    • GCPだといい感じのグッズがあるだとか、AWSのALBと相性が悪いっぽいとかの噂を聞く
  • grpc-gateway
    • gRPCはバイナリプロトコルということもあって、gRPCに対応しづらいシステムからアクセスできなかったり、気楽にcurlで試せなかったりする
    • gRPCのメソッドにそれぞれ対応するREST APIを生やしてくれるグッズがあるらしいので試してみる。実運用ではどうせこういうのが必要そう
  • 意味のあるgRPCを喋るアプリケーションの開発
    • もうちょっと現実味のある課題に出会えるかもしれない

やっていく技術テーマを探す

Webエンジニアを8年くらいやっていて、なんとなく、一通りのことはできるようになってきた。ただ、ちょっと得意な分野もあるとはいえ、基本的になんでも屋さんとしてやっているので、技術者としてのアピールがいまいちだなーというのが気になっている。そこで、技術者としての自分をアピールできそうな技術テーマを一つ選んで、それにじっくり取り組んで見ようと考えた。

しかし、取り組む技術テーマをうまく選ぶ自信がない。そこで、ちょっと作戦を考えて取り組む技術テーマを見つけようと試行錯誤してみたので紹介してみる。

ステップ1: 指標を考える

やっていく技術テーマを見つけるにあたって、テーマの候補をスコアリングしてみることにした。漠然とスコアをつけるのは難しいので、自分が普段技術テーマに取り組むかどうかを考えるときに気にしていることを思い出して、5つの指標に分解してみた。

  • 指標1: 自分の興味
    • 自分がおもしろい、やりたいと思うかどうか
    • モチベーションがないとやりはじめることもできない
  • 指標2: すぐに役立つか
    • すばやく学べて、すぐに実際の問題解決に活かせるかどうか
    • すばやく成果が出せるとうれしいし、モチベーションも持続する
  • 指標3: 長く役立つか
    • 流行り廃りに影響されにくく、将来に渡って活用できそうか
    • 学んだことが無駄になりにくいし、多くは下地になるような技術だろうから基礎力がつく。 この記事でもそういった話題について言及してる
  • 指標4: Web技術者人気
    • Web技術者にとって人気があって注目されているか
    • いろんな人に役立ったほうがうれしいし、評価もされやすい
  • 指標5: ブルーオーシャン度
    • 取り組んでいる人が少ないか
    • 競争相手が少ないほうがのびのび取り組めるし、第一人者になりやすい
    • (追記 2018/03/18 9:00: この指標はしっくり来てない感じはある。自分が入り込む余地があるかというイメージなので"スペースがあるか"くらいが良さそうかな。)

あくまでも僕が何を大事にして技術テーマを選びたいかに基づいている。人によってはブルーオーシャンかどうかは気にしないとか、もっと別の評価軸があるとかはあると思うので各々考えると良いと思う。とにかく分解して考えられるようにする。

ステップ2: 取り組めそうな技術テーマを羅列する

まぁ、これは良さそうなテーマを思いつく限り羅列する。会社の人とかにも聞いてみたりした。

ここでは、ポケモンエンジニアリング、エンジニアの学び方、機械学習、Goというテーマが思いついたとする。自分は20個くらい思いついた。

ステップ3: 技術テーマにスコアをつける

ステップ1で考えた指標にもとづいて点数をつけて表にする。点数の付け方はなんでも良いと思うけど、13までのフィボナッチ数を使ってみた。仕事でタスクの見積もりとかでよく使っているので、自分は相対感がつけやすい。

例として選んだテーマについてめちゃくちゃ適当に点数を埋めてみた表が以下のようになる。実際にはGoogle Spreadsheetを使ってる。

技術テーマ 自分の興味 Web技術者人気 すぐに役立つか 長く役立つか ブルーオーシャン度 合計値
エンジニアの学び方 8 13 8 13 5 47
ポケモンエンジニアリング 13 2 8 3 13 39
IoT 8 8 5 13 1 35
Go 8 8 8 8 3 35

この表にうめている点数はめちゃくちゃ適当につけたやつなので、本当に意味はない。目的は自分のやっていく技術テーマを決めることなので、実際には主観的にえいやっと点数を決めていくと良いと思う。自分の興味とかはそもそも主観的だし、Web技術者からの人気なども自分の判断で決めるしかないだろう。

点数をつけ終わり、合計値のランキングの上位を調べることで、自分にとっての有望な技術テーマがわかってくるはず。

ステップ4: レーダーチャートで可視化する

ステップ3までを自分でやってみたところ、合計値ランキングの上位の技術テーマが似たような点数になったので、点数の傾向がひと目でわかるようにレーダーチャートで可視化してみた。

例の表のデータを使って可視化してみると、以下のようになる。

f:id:hakobe932:20180317174538p:plain

これで、分析がしやすくなった。このレーダーチャートはChart.jsを使ってサクッとつくった。GitHubにコードをおいてある。

感想

実際やってみてて、どうだったかというと、ランキング上位になった技術テーマのラインナップを眺めると、大方まぁそうですねという感じであった。だが、1つだけ自分の興味がめちゃくちゃ低いが、他のスコアが高いために上位にランクインしているテーマがあり、ふーむなるほどねという発見があった。逆にランキング下位になった技術テーマにも、自分では良さそうに思っていたテーマのスコアが意外と低いということがあった。

指標を分けてそれぞれ評価することで、多少は客観的な評価ができたのだと思う。副作用的に指標を考えることで自分が技術テーマについて何を大事に思っているかを整理できたのも良かった。

さらにスコアの内訳をレーダーチャートで眺めると、平均的に全部が良いテーマはなく、指標が偏っていることがわかるなど発見があった。上位テーマのスコアは点数が似たり寄ったりなのだが、5つの指標の中から何を大事にしていくかを考えていけば、自ずと良さそうなテーマに辿り着けそう。

正直まだ点数を見直したりして、やっていく技術テーマを決められていないのだけど、このままではワナビーで終わってしまうので、このあとえいやっと決めようと思う。

Fluent Pythonを読んだ

Fluent Python ―Pythonicな思考とコーディング手法

Fluent Python ―Pythonicな思考とコーディング手法

ちょいちょいPythonのコードを書くことが出てきたので、ちゃんとした使い方を学ぶために読んでみた。Pythonic にオレはなる!

目次 を見るとわかるのだけど、データ構造、関数、オブジェクト、制御構造、メタプログラミングと言語の機能を広く深く取り扱っていて、Pythonをしっかり理解するという目的にはぴったりだった。Pythonの基本文法は抑えてるのが前提になっているので、初学者は入門 Python 3あたりを読んでおくと良いと思う。

この本が良いのは、各章ごとに参考文献がかなり充実している点だ。章の終わりに油断していると何ページも資料の紹介が続いてびっくりする。各トピックについて本書の内容だけでもよく説明されているのだが、さらに踏み込んで調べられるように、ドキュメントや書籍、役に立つ記事をコメント付きで紹介してくれている。ときにはフォーラムやカンファレンスでの発表へのリファレンスもあり、コミュニティがどこでも盛り上がっているのかも自ずと伝わってくる。著者がPythonコミュニティで長年活躍されているなかで得られた知見を、効率良く摂取できる本になっている。

また、Pythonの様々な言語機能の実現メカニズムを学ぶことを通して、Pythonの設計思想全体を学べる構成になっているのも良い。例えば、抽象基底クラスを実装しているかどうかは、isinstance関数を用いてチェックできるのだが、これはデフォルトでは継承関係によってチェックされる。しかし、実は特殊メソッドである __instancecheck__ の実装により振る舞いをオーバーライドすることで、特定のメソッドを実装していることで実質的に同じクラスとみなして良いかをチェックできるようになっている。これはPythonがもともと持つダックタイピングの考え方を、Python的特殊メソッドを用いて導入していたりするわけで、なかなか面白い。機能ごとに、こういう実装パターンを学んでいくことで、自ずとPythonicな考え方がみについてくる(ような気がする)。

原著がPython3.4あたりベースなのでちょっと古いのには注意したい。最近のPythonだったら f stringやasync awaitなど、紹介されている機能のより良い代替手段があったりする。

とにかくページが多く読むのは大変なのだけど、上記のようにPython的考え方を密度高く学べるので読んで損はないと思う。加えて著者の熱量が高く、そこらかしこで良いことを教えてくれるので、Pythonの話題にかぎらずかっこいいハッカーの考え方を盗める良い本だと思う。