2020年の振り返り

仕事

2020年はフリーランスをやめて社員として就職したのが大きな出来事だった。就職活動の中でコロナが拡大して非常事態宣言も出てしまったので、正直いうと決断がかなり守りに入ったものになったかなと今振り返って思う。

入ったのは新卒時に入った会社と同じくらい大きな会社で、これまでの経験を活かしながら今までと全く違う領域のソフトウェア開発に携われること、今大きな会社もソフトウェアの内製化に舵を切っているので日本の大企業の方がむしろ大きなうねりを作り出せるんじゃないかと感じたのが理由だった。正直いうと他のスタートアップの方が条件ではちょっといいくらいだったが、仕事内容は魅力的に映った。

ただこれもコロナの大きな影響を受け、関わるはずだったプロジェクトも大きく変わり、更には給与面も入社し二ヶ月でかなり下がったりして、正直モチベーション的にはかなりしんどかった。あとこれ何の役に立つの…?というものだったり、偉い誰か向けのデモのための間に合わせの何かを作ったりということが多く、プロジェクト状況的にしかたない面もあるが本当にしんどかった。

とはいえこういったことはある程度覚悟の上で入ったわけで、自分の力が足りなかったということなんだろうと思う。しんどいけど。

来年からはまた大きく環境が変わるので頑張っていきたいと思う。

技術

始めたのは去年の10月とかなのだけど、1月にCouseraの機械学習コースを修了した。実務では使わなかったのだけど、機械学習の基本的なアイディアというか考え方を基礎から理解できたことはとてもよかったなと思う。 suzan2go.hatenablog.com

入社して2ヶ月くらいはk8sを結構触っていたので、事前にCKADを取っておいてよかった。 suzan2go.hatenablog.com

その後はなぜかC++をやっていた。C++は大学院以来でかなり自分の知識が古いことが分かったけど、意外となんとかなった。主にはEnvoy関連のことやっていたがC++とEnvoy自体とネットワークプロトコルの両方を理解している必要があって中々しんどいものがあったが勉強にはなった。

suzan2go.hatenablog.com

英語

チームメイトに非日本語話者がいたので、特に英語を頑張っていた。よくある英語字幕で見たりということもやっていたけど興味のない作品だと続かないので、結局アマプラでシリコンバレーシリーズを日本語字幕で10週くらいしていた。おかげで使う機会のない汚い表現がたくさん身についた気がする。

11月からは2月に始めてすぐに緊急事態宣言になってしまって行けなかった英会話教室(Gaba)をリモートで再開した。本来半年で切れる受講期限が2021年の2月まで伸びたのはありがたい。。講師の中にはシリコンバレーで働いていた人だったり、元ソフトウェアエンジニアだったりがいるのでそういう人を中心に週2でレッスンを受けている。 Gabaに特に不満もないし他の英会話サービスは使ってないので比較できないのだけど、正直全部リモートだとちょっと割高かなぁと思わなくもない。ただ怠惰な自分の性格的に高い金を注ぎ込まないとやらないかなーと思っている。

その他

流行りの昇降デスクを購入した。デスク自体も満足しているが、これに伴って部屋のレイアウト変えたのが良かったなと思う。以前は窓に背を向けるレイアウトで時間の流れを感じられなかったが、いまは左手に窓が見えるので日の光の変化を感じられるのがよい。 suzan2go.hatenablog.com

NuroのONUに付いてくるWifiが時々不安定だったので、linksysというものに変えて一階と二階に機器を置いてネットワークを作っている。 www.linksys.com

来年

来年からは日本語ネイティブの開発者は自分だけの環境に飛び込むことになった。向こうも自分の英語のレベル感について理解はしていると思うけど、クビにならないように頑張りたい。。。

デスクを昇降デスクに買い替えた

自宅の作業環境として使っていた木製のPCデスクから、FLEXISPOTの昇降デスクに買い替えました。

購入した理由

二人目の子供が生まれてからは中々家で集中して仕事をするのが難しく、コロナ以前は基本的にオフィスやコワーキングスペースで仕事をすることを選んできました。コロナが収まったらできれば家の外で仕事をしたいと考えていたのですが、あと1年はオフィス中心に仕事をすることはなさそうなので、自宅作業環境に投資をすることに決めたのでした。

購入したもの

購入したのはもはや定番感あるFLEXISPOTです。FLEXISPOTといってもいくつか種類があるので注意が必要です。以下のリンクの比較表がよくまとまっています。例えば1時間おきに立ったり座ったりといった使い方を予定している方は、停止位置を記録しておける記録機能は必須じゃないかなと思います。

Amazon.co.jp: FLEXISPOT: スタンディングデスク 対応表

FLEXISPOTはAmazonでも購入できますが、公式サイトにしかないセットや周辺グッズがあったり、たまにキャンペーンをやっていたりするのでタイミングによっては公式で買ったほうがお得のようです。自分は公式サイトからE7というグレードのセットを購入しました。また公式サイトからだと天板の色やフレームの色などを選択して注文できます。

flexispot.jp

インターネット上だと天板を自作するガチな方が多かったのでちょっと迷いましたが、小さい子供が遊び回る家のなかで重い天板を仕上げる覚悟がなかったので、自分は普通に140x70cmの天板をセットで購入しました。

組み立て

ブログのために写真を撮っておけばよかったのだけど天板と土台となる足がそれぞれ別で来ました。噂には聞いてましたがマジで重いので、非力な方だと部屋まで持っていくのもかなりしんどいと思われます。確か30kgとかなんとか。

完成

f:id:suzan2go:20201112000127j:plain スピーカーやディスプレイなどもおいているのでかなり重いはずだけど、普通に昇降します。

もともとは以下のパーツを使って足元のミドルタワーPCもデスクにつけて昇降するようにしていました。しかし、座ったときに足元がかなり狭くなるのと、宙にうくミドルタワーの視覚的な圧迫感がすごくて、結局床置きにしてしまいました。微妙に足元に見切れているキーボードは仕事で使うエッジコンピュータに接続する用で、普段使いのときは必要ない…はず。

https://flexispot.jp/media/catalog/layer/cache/x560/c/h/ch101-g.jpg

FlexiSpot | CPUスタンドCH1B

感想

メモリ機能が便利

立つとき、座るときにいちいち丁度いい高さに調整するのは面倒だと思うのだけど、これならワンタッチで指定した高さまで昇降できます。自分は1時間おきに立ったり座ったりする使い方をしているので、これがないと結構不便だったろうなと思います。シリーズによっては単純な昇降ボタンしかないものもあるので、注意が必要です。

https://flexispot.jp/media/wysiwyg/description/E7/E7-490300-3.jpg

マットが意外と良い(が、でかい)

FLEXISPOTの公式で立っているとき用のマットが買えるのですが、これがなかなか結構デカイです。ただマットはあったほうが足腰には良さそうで、感触もなかなか気持ちが良いので気に入っています。公式の画像をみると靴を履いて使うことを前提にしている気がするけど、気にせず素足で使ってます。

70センチの奥行きがちょうどよい

もともと60センチの奥行きのものを使っていたので、70センチの奥行きはちょっとでかいかなと思ったのですが、結果ちょうどよかったです。自分は視線が左右にブレるのが嫌で、ディスプレイとマックを同じ直線上に並べて使っているのですが、それでも手元に余裕があるのがなかなかよいです。

ぼーっとしなくなった

ずーっと座っていると夕方くらいには頭がぼーっとしたり体のだるさを感じたりしていました。昇降デスクが届いたあとは1時間おきにスタンディングスタイルに切り替えているのですが、頗る体調がよいのと、以前に比べて夕方まで集中力が続くようになったな〜と感じます。

その他

スタンディングデスクスタイルにしておけば子供に机の上を荒らされずに済みます。ただ机の下に入り込まれて延々と遊ばれるデメリットもあります…

まとめ

スタンディングデスクはいいぞ

Envoyのフィルターを自作してみる

仕事でEnvoyのフィルターを書いているので、学んだことをまとめておく。

Envoyとは

github.com

Cloud-native high-performance edge/middle/service proxy ということでこれ自体はnginxと同じようなproxyなのだけれど、多様な機能を持っていて、サービスメッシュのデータプレーンに用いられていたりする(とプロダクションで使ったことないけど理解している)。

最近だとDropBoxがnginxからEnvoyに切り替えて色々めちゃよくなりましたというブログが投稿されて話題になっていたりした。

dropbox.tech

Envoyのフィルターについて

Envoyのコア機能に影響を与えず、Envoyの機能を拡張できるのがフィルター。

f:id:suzan2go:20200828103455p:plain 引用 : 今日から始める Envoy | Lizan Zhou

Envoyは多様なフィルターがデフォルトで組み込まれている(下記もほんの一部)が、実行時に動的に自作のプラグインを足したりといったことはできない。 f:id:suzan2go:20200828101405p:plain

そのため自作のフィルターをEnvoyに足すためには、自分たちで自作のフィルターを含める形でEnvoy自体を1からビルドする必要がある

Envoyのビルド環境を作成する

EnvoyはC++で記述されているが、ビルドにはbazelというGoogle産のツールを使用しているのと、ビルドにあたってはいくつかのライブラリをインストールしておく必要がある。 以下に詳細がまとまっているので確認するとよい。 https://github.com/envoyproxy/envoy/blob/7b8ab2dcd21c14b412e88e847b246d0a8159890b/bazel/README.md#building-envoy-with-bazel

注意することとして、bazelを直接インストールするのではなく、READMEに沿って bazelisk というツールを使ってbazelを使用したほうがよい。というのもbazelのバージョンを指定してインストールするのがちょっと面倒なのとバージョン差分でビルドできないとめっちゃハマるので…(実際ハマった…) bazeliskを使うことでワークスペースに応じたbazelを自動でインストールして実行してくれる。

bazel自体もそれなりに複雑なプロダクトなので、C++用のチュートリアルをやっておくと雰囲気がつかめてよい。

Build Tutorial - C++ - Bazel

Envoyのビルドは割と高スペックなMacでもクリーンビルドだと1時間近くかかるので、手元のマシンが貧弱な場合は高スペックなEC2インスタンスを立てて使ってみるのもありかもしれない。実際Envoyにコミットされているエンジニアの方はビルド用の自作PCを組んだりしているらしい…

どのエディタ/IDEを使うか

普段からJetBrains製のIDEを使っているので、自分はJetBrainsが出しているCLionというC と C++用のIDEを使っている。ただしCLionはbazelのビルドに対応していないので、デフォルトだと補完や定義ジャンプがうまく動かない。 そこでCLionがサポートしているcmakelistsをbazelから出力する以下のスクリプトがある。が、このスクリプトを使っても後述する *.proto ファイルから自動生成されるC++ファイルのへ参照はうまくいかない。 https://github.com/lizan/bazel-cmakelists

VSCodeにちょっと浮気してみたところ、上記のcmakelistsなしでも定義ジャンプ、補完、さらには自動生成ファイルへの参照も動いたので、自分はVSCodeに移行するかもしれない。

Envoyのカスタムフィルターを作成する

envoyproxy/envoy-filter-exampleというリポジトリが用意されているので、これをベースに開発を進めていくのがよさそう。

github.com

このリポジトリは中身を見るとわかるように、以下のような構成になっている。

bazelのBUILDファイル自体については説明しないが、以下のような形で自分たちの書いたコードとEnvoyを一緒にビルドするような感じになっている(雰囲気だけお伝え)

envoy_cc_binary(
    name = "envoy",
    repository = "@envoy",
    deps = [
        ":http_filter_config", <= 自作のフィルタ
        "@envoy//source/exe:envoy_main_entry_lib",
    ],
)

api_proto_package()

envoy_cc_library(
    name = "http_filter_lib",
    srcs = ["http_filter.cc"],
    hdrs = ["http_filter.h"],
    repository = "@envoy",
    deps = [
        ":pkg_cc_proto",
        "@envoy//source/extensions/filters/http/common:pass_through_filter_lib",
    ],
)

envoy_cc_library(
    name = "http_filter_config",
    srcs = ["http_filter_config.cc"],
    repository = "@envoy",
    deps = [
        ":http_filter_lib",
        "@envoy//include/envoy/server:filter_config_interface",
    ],
)

Envoyのフィルターの構成を理解する

中身の実装についての詳細な解説はたぶんないので、実際にEnvoyのリポジトリにあるフィルターのソースコードを見ながらどんなことをやっているか把握するのがよい(正直自分も全然わからない俺たちは雰囲気で…という状態...)。フィルタのソースコードは以下のパスの配下にある。

envoy/source/extensions/filters

フィルターはだいたい以下のファイルから構成されている

  • xxx_filter.cc / xxx_filter.h
    • フィルターの実際の中身の処理を記述する。 httplistnernetwork といった種類のフィルタがあり、それぞれベースとなるクラスが用意されている。フィルターはそれらのクラスを継承して実装を行う。
  • config.cc / config.h
    • configというとこのフィルタ自体の設定値を管理するようなイメージがあるが、実際にやっていることは envoy.yaml から設定値を読み込みフィルターのコンストラクタに渡すこと、REGISTER_FACTORY というマクロを呼んでEnvoyにこのフィルタを登録すること、である。
  • xxxx.proto
    • Protocol Buffersというファイルで、ここにフィルターで使う設定値の定義を行う。このファイルをもとにbazelによりC++ファイルに変換される。ソースコード上で #include "envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.pb.h" のように pb.* となっているファイルはprotoファイルをもとに生成されたC++のコード。

例えばAWS Lambdaを起動するenvoyのフィルタは以下のようなファイルから構成されている。

f:id:suzan2go:20200828101519p:plain

ここにはprotoファイルが定義されていないが、それはEnvoyのソースコード上では別ディレクトリで管理されているため。ちなみに AWS Lambdaの.protoファイルは以下のようになっている。

syntax = "proto3";

package envoy.extensions.filters.http.aws_lambda.v3;

import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.http.aws_lambda.v3";
option java_outer_classname = "AwsLambdaProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: AWS Lambda]
// AWS Lambda :ref:`configuration overview <config_http_filters_aws_lambda>`.
// [#extension: envoy.filters.http.aws_lambda]

// AWS Lambda filter config
message Config {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.aws_lambda.v2alpha.Config";

  enum InvocationMode {
    // This is the more common mode of invocation, in which Lambda responds after it has completed the function. In
    // this mode the output of the Lambda function becomes the response of the HTTP request.
    SYNCHRONOUS = 0;

    // In this mode Lambda responds immediately but continues to process the function asynchronously. This mode can be
    // used to signal events for example. In this mode, Lambda responds with an acknowledgment that it received the
    // call which is translated to an HTTP 200 OK by the filter.
    ASYNCHRONOUS = 1;
  }

  // The ARN of the AWS Lambda to invoke when the filter is engaged
  // Must be in the following format:
  // arn:<partition>:lambda:<region>:<account-number>:function:<function-name>
  string arn = 1 [(validate.rules).string = {min_len: 1}];

  // Whether to transform the request (headers and body) to a JSON payload or pass it as is.
  bool payload_passthrough = 2;

  // Determines the way to invoke the Lambda function.
  InvocationMode invocation_mode = 3 [(validate.rules).enum = {defined_only: true}];
}

// Per-route configuration for AWS Lambda. This can be useful when invoking a different Lambda function or a different
// version of the same Lambda depending on the route.
message PerRouteConfig {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.aws_lambda.v2alpha.PerRouteConfig";

  Config invoke_config = 1;
}

ここで定義されたprotoファイルのパッケージ名はenvoy.yamlでenvoyの設定値を書くときにも以下のように使われる。

          typed_config:
            '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
            grpc_service:
              envoy_grpc:
                cluster_name: ext-authz

Envoyのフィルターを実際に書いてみる

解説できるほどまだ理解できていないが、基本的な考え方としてベースとなるフィルターに定義されているメソッドがいくつかあるので、必要なものを実装していけばよい。例えばHTTP Filterなら以下のようなメソッドを実装して目的となる処理を実装すればよい。

HttpSampleDecoderFilterConfig::HttpSampleDecoderFilterConfig(
    const sample::Decoder& proto_config)
    
HttpSampleDecoderFilter::HttpSampleDecoderFilter(HttpSampleDecoderFilterConfigSharedPtr config)

HttpSampleDecoderFilter::~HttpSampleDecoderFilter() {}

void HttpSampleDecoderFilter::onDestroy() {}
const LowerCaseString HttpSampleDecoderFilter::headerKey() 

const std::string HttpSampleDecoderFilter::headerValue() 

FilterHeadersStatus HttpSampleDecoderFilter::decodeHeaders(RequestHeaderMap& headers, bool)

FilterDataStatus HttpSampleDecoderFilter::decodeData(Buffer::Instance&, bool)

また FilterHeadersStatus を戻り値として指定されている関数は、戻す値によってその後のフィルタの挙動を制御できるようになっている。

    // 次の処理に進む
    return Http::FilterTrailersStatus::Continue
    // フィルターでの処理を中断する
    return Http::FilterTrailersStatus::StopIteration

configについては、以下の点を抑えておけば既存のフィルターを参考にしつつかけると思う。

  // https://github.com/envoyproxy/envoy-filter-example/blob/a994541170218e12129977539ef96b0f672f7369/http-filter-example/http_filter_config.cc
  /**
   *  Return the Protobuf Message that represents your config incase you have config proto
   */
  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
    return ProtobufTypes::MessagePtr{new sample::Decoder()}; // protobufから自動生成したクラスを渡す。これをやらないとyamlからのデシリアライズに失敗する
  }

  std::string name() const override { return "sample"; }  // この名前がfilterの名前になる

あとは、既存のフィルターの実装などを参考にしながら頑張るしかない。サンプルリポジトリで実装されているフィルターはシンプルなので全容を把握するのによいと思う。

参考資料

一緒に仕事している @tomoyaamachiさんの資料。色々と教えていただきました :bow: scrapbox.io

Enterprise IoT: Strategies and Best Practices を読んだ

上司になる人に、「事業ドメインへの理解が足りないので勉強になる本があれば教えてください」と聞いたらこの本を紹介されたので読んだ。

洋書の専門書を読むのは大学の研究室以来で正直結構しんどかったけど、自分の経験に近い領域のところは比較的楽に読めたので頑張れた。

感想

The Ignite | IoT Methodology というIoTビジネスをやっていく上での方法論の紹介とケーススタディが中心となっている本。 エンタープライズと名前がついているだけあって、ある程度大企業を前提としてどのようにIoTサービスを作り出していくのかが、技術的・ビジネス的な側面から述べられている。個人的に面白かったのは、製造業と、インターネットサービスという2つの性質の違う世界をどうしていけばいいのか「Clash of Two Worlds: Machine Camp Versus Internet Camp」について。文化的な違い、開発サイクルの違い、アジャイル vs ウォーターフォール、同じ製品に対するサービス開発のアプローチの仕方の違いなどが指摘されていて、納得感があった。ただ、じゃあどうすればいの?という質問に対しては、明確な解は特に提示されてなかった気はする。このへんはプロジェクトの規模にもよるので仕方がないとは思うけど。

上記意外では、以下のような話が印象に残っている。

  • IoTビジネスの難しさ
    • そしてデバイスのコストが低く見積もられがち。PoCの段階ではラズパイのようなもんで行けても、実運用では使えない…ということはよくあるらしい。デバイスが大量に必要なサービスではコストが想定よりかかってしまうと、事業への影響がかなり大きい。
    • 売り切りの商品に対する IoTサービスでは商品価格にIoTサービスのコストを乗せる必要があり価格設定が難しい
    • バイスもそうだが大量のデータを最初から取り扱う必要がある場合が多く、コストの面で普通のSaaSなどよりも厳しい。
  • IoTサービスのアーキテクチャについて
    • すべてをバックエンド(クラウド)に集めるのでは通信コストや、データ保存コストが高くなりすぎる場合がある
    • ゲートウェイを用意して一度そこで集約したり、デバイス側にロジックをもたせて計算後にバックエンドにあげるアーキテクチャも選択肢の一つとなる

技術面とビジネス面の両方でこれまで知らなかったことを網羅的に知ることができ、とても勉強になる本だった。自分は一応一通り目を通したけど、自分の関わる仕事と関係の薄い技術に関するお話はサクッと飛ばしても良さそう。

CKAD(Certified Kubernetes Application Developer) を取得した

次の職場でK8sを結構触ることになりそうなので、K8sについて幅広く知っておきたくて勉強のために取得した。自分でGKEに何か立ててみるでもよかったのだけど、過去に趣味でやったことがあったし、何となく動いたーで終わっちゃいそうだったので、体系的に学ぶために受験を決めた。試験も選択肢から答えを選ぶような形式でなく、実際にコマンドやyamlを書いてapplyするという実戦形式だったのも受験の後押しになった。

こちらはK8sを利用する開発者向けの資格なのだけど、Certified Kubernetes Administrator (CKA)というクラスタ管理者向けの資格もある。K8s自体がどうやって動いているかなどはCKAの方が勉強になりそうなので、そちらも取得するつもり。

受験前の自分の経験値

インフラエンジニア / SREではなく、アプリケーションエンジニア。K8sはGKEは自分の個人アプリで試しにつかってみたり、仕事でSREの人が用意したYamlを読んだりいじったりした程度の経験値。Pod / Deployment / Serviceなどの概念についての理解はあった。

やったこと

CKADでgoogle検索すると色んな方の体験記が出てきたので、それを参考に以下のようなことをやった。勉強期間は大体2週間くらい(仕事は週2〜3くらいに抑えた)。

Kubernetes完全ガイドを読んだ

体験記の殆どの人がこの本を読んだと書いてあったので、自分も購入して読んだ。K8s関連のことが体系的にまとまっていて、まずこれを読んでK8sについて全体感を掴んだのはとても良かったと思う。完全ガイドというだけあって、単純に概念を紹介するだけでなく内部的なアーキテクチャに踏み込んだ説明もあって、理解が深まった。

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)

  • 作者:青山 真也
  • 発売日: 2018/09/21
  • メディア: 単行本(ソフトカバー)

Linux AcademyのCKADコースを取った

ビデオでCKADの出題範囲について学ぶコース + いくつかの模擬試験付き。ビデオと資料は全て英語で英語字幕しかないが、かなり丁寧に説明してくれるので英語に苦手意識がなければ大丈夫だと思う。またHands-On Labsという機能があり、サービスが用意してくれる練習用のK8sクラスターにsshして実際にkubectlコマンドを叩くことができる。

linuxacademy.com

コース自体に全く不満はないものの、月額$49で全てのコースが見られるという料金プランしかないので、CKAD以外に特に受けたいものがない場合はちょっとコスパが悪いかもしれない。

Udemyならセール期間なら¥24,000が93%OFFで¥1,610になっていたりするので、セール中に買えるならこちらをお勧めする。模擬試験の問題もこちらの方が多い。 Kubernetes Certified Application Developer (CKAD) Training | Udemy

github.com/dgkanatsios/CKAD-exercises

CKADのための練習問題がまとまっている。この問題がそのまま出るわけではないけど、これがスラスラ解けるようになれば合格できると思う。練習を始めるときにGKE上に環境を立ち上げて、練習が終わったら消す…みたいなことを以下のようなMakefileを作って簡単にできるようにしておいた。

setup:
    gcloud container clusters create k8s --cluster-version 1.14.10-gke.27 --zone asia-northeast1-a --num-nodes 2 &&\
        gcloud container clusters get-credentials k8s --zone asia-northeast1-a
cleanup:
    gcloud container clusters delete k8s --zone asia-northeast1-a

わからない問題があるとついついググりたくなってしまうけど、試験中はK8s公式のドキュメントしか参照できない(しかも試験とは別に開けるタブは1つだけ!)ので Kubernetes Documentation - Kubernetes で調べる癖をつけて、特に設定が複雑なやつはブックマークしておくと良い。自分はConfigMapとSecretをボリュームとしてマウント、環境変数として設定する方法がなかなかスッと覚えられなかったのでブックマークしてすぐにページを開けるようにしておいた。

github.com

Linux Academyのコースの進捗に合わせて一回、 Linux Academyのコースを全部やった後に一回、試験前に一回と合計3週した。試験前には3時間くらいで全部のエクササイズが終わるようになっていた気がする。

他には試験についてtipsがまとまっている以下のページも目を通した。 github.com

試験本番

試験部屋の準備

試験中だれも入ってこない、静かな部屋で、机の上にPC以外のものがない状態にできるならOKということだった。自分が普段使っている机は物が多くて片付けるのが不可能だったので、寝室にちゃぶ台を持ち込んで受験した。部屋自体にものがあっても問題ないと思うのだけど、机の上に電子機器やノートを置かずにキレイにするという条件は結構厳格っぽいので、机の上にスピーカーやスキャナー、プリンターとか置いてあるなら片付けておくのが無難な気がする。

試験前の試験管とのやりとり

試験前に机や部屋の状態、IDのチェックが行われた。

受験記によってはパスポートが必須とあったのだけど、ガイドを読む限りは運転免許証とクレジットカードで良さそうだったので、そちらを準備して待機。試験前のチェックが始まり、試験管に運転免許証とクレカを見せたら「アルファベットで書かれたIDは持ってないの?」と聞かれて、終わったか…?と思ったけど大丈夫だった。最初からパスポートは持ってません!って言った方がスムーズだったかも。あとMacの強制終了メニューを見せてくれと言われて指示されたコマンドを押したのだけど、karabinerのせいで反応せず焦ったりした。

試験

試験が始まるとWEB上に問題文と回答用のコンソールが表示される。試験のためのサイトが大分古臭かったので不安だったのだけど、試験自体のUIは割と洗練されていて、WEBのコンソールもスムーズで特にイライラさせられることはなかった。コピペがctrl + c でできないなどの制約があるのでそれは注意。(Macの場合は⌘ + cは普通に使えます)

時間が足りない!という感想が多かったのでかなり身構えていたのだけれど、自分の場合はたまたま簡単だったのか30分くらい時間が余ってしまって逆に不安になった。基本的に1からyamlを書いたりせず、kubectl editで済ませたり、dry-runしてyamlの雛形を作ったり、ブックマークしておいた公式ドキュメントのページからコピーアンドペースト(公式ドキュメントの参照は認められている)するようにしていたのが良かったのかもしれない。

結果

試験終了後に「36時間以内に結果を連絡するよ!」というメールが来る。自分の場合はだいたい30時間後に連絡がきた。特にわからなかった問題はなかったのだけど、ボーダー66%のところ91%だった。一通り見返したはずだけどnamespaceとかで何かミスっていたのかもしれない…

よかったこと

実際の開発現場でガンガンkubectl editしたり、手元のyamlファイルを本番にapplyしたり…みたいなことは基本ないとは思うのだけど、kubectlのコマンドになれることでK8sのリソースに対する理解も深まったと思う。またどなたかのブログにも書かれていたのだけど、busyboxなどで一時的にpodを作ってデバッグする、、、あるいは既存のpod上でデバッグのために何かを実行してみる、、、といった操作は本を読んだだけだとなかなか身につかないと思うので、手を動かすことが身につけられたのは良かった。

今後

CKADはK8sを利用する開発者向けということもあって、K8s自体に踏み込んだことは完全ガイドのほかは特に勉強できていない。UdemyでCKAのコースも取ってみて、もう少しK8s自体について詳しくなりたいな〜と思っている。

CourseraにてStanford Universityの機械学習講座を修了した

www.coursera.org

やろうと思ったモチベーション

機械学習については前職の機械学習エンジニアの同僚の知識量とか能力が圧倒的で追いつける気がしなかったので、専門家にまかせて自分はWEBに集中していればいいかなと思っていた。ただフリーランスとして手伝っていた会社の殆で、必ずしも専門家でない人たちが機械学習を何らかの形で活用していて、これは少なくとも知識として知っておかなくてはまずいという気持ちになったため。

もともとはDL4USという東大松尾研が中心にやっているオンライン講座を受けようと思っていたのだけど運悪く抽選に漏れてしまったので、よく評判を聞くCourseraのStanford Universityの機械学習講座に勢いで申し込んだ。

進め方

基本的にオンラインで自由に進めていいのだけど、10月〜12月のように講座期間が設定してあってその中で一週間ごとにすすめるようなスケジュールがデフォルトで組まれている。自分は10月の後半から始めたのだけど、11月が予想外に忙しくなってしまったため、1ヶ月くらい休んで12月から再開した。毎週WEB上でできるクイズとプログラミング課題の締め切りの日時が設定されているけど、期限を過ぎても最終締め切りまでに出せばいいのと、追いつくのが難しいほど遅れてしまった場合には、次の講座期間にスライドすることも可能になっている。

ビデオは毎週2時間前後で、プログラミング課題は所要時間が3時間程度で作られている。プログラミング課題はスッと実装できれば1時間くらいで終わるが、はまると何だかんだ3時間くらいかかってしまったこともあった。

感想

講座の難易度が絶妙で実践と理論のバランスがとてもいいなと思った。「この数式の詳細はこの講座の範囲を超えるので理解できなくてもよい」、「この数式がピンとこない場合はXXを再度復習してみてほしい」など抜いていいところと必ず理解する必要がある箇所をちゃんと区別して教えてくれるし、かなり順を追って丁寧に解説をしてくれるので急に意味不明な数式が登場して置いてけぼりにされる…みたいなことがなかった。

数学については大学で理系だった人は特に困らないのではと思う。自分は情報系ではないのだけど大学院で似たような数値計算を扱ったことがあって、これは機械学習文脈で扱うとこうなるのかーーーと思ったりした。

講義は英語だけど日本語字幕がつくし、Andrew先生がかなり丁寧目に話してくれているので、理解には困らなかった。ただし、2、3は字幕の無いビデオがあったのと、訳の質はまちまち。たまに英語とワンテンポずれてて混乱するので英語字幕にして見たりしていた。あと講座の資料、テスト、プログラミング課題は全て英語なので、手厚い日本語サポートを期待しているとちょっと面食らうかもしれない。

あとプログラミング課題がOctaveという言語というのに最初は面食らっていたけど、そんなに変なシンタックスもないしすぐ慣れるし慣れてくると特に困らなかった。Andrew先生が「Python / R / C++も試したけど、学生がアルゴリズムをすぐ試すのにはOctaveが一番適していた」的なことを言っていたのだけど確かにその通りだなと思う。行列計算などに必要な機能を言語組み込みで持っているというのがでかいのかな。

得たもの

講座自体がもう結構前に作られたものなので最新の機械学習について学べる!というわけではないと思うのだけど、ベースとなる知識は獲得できたかなと思う。というのも今まで読んでも意味不明だった機械学習エンジニアの書いたブログポストがある程度は理解できるようになっていたから。前述のとおり講座で使った言語はOctaveだし、この講座を修了したからといって機械学習を専門として扱えるようになるわけではないと思うのだけど、今後機械学習案件に携わるときに完璧じゃないにしろその中身を理解できるようになったのは大きいかなと。今はMLOpsという周辺の領域も盛り上がっているので、そういうところで活かしたい。

まとめ

敷居が高いように見えるけど、日本語字幕も殆どついてるし、なによりとても説明が分かりやすいのでCoursera Stanford Machine Learningはお勧めです。

アルゴリズム図鑑 を読んだ

アルゴリズム図鑑 絵で見てわかる26のアルゴリズム

アルゴリズム図鑑 絵で見てわかる26のアルゴリズム

Amazonで評判が良かったので買ったけどさすがに簡単過ぎた。とはいえ非エンジニアや中高生なんかが読む本としてはなかなかいいんじゃなかろうか。