日本からバンクーバーに移住して生活を安定させるまでにやったこと

2023 年 7 月 26 日に日本からカナダのバンクーバーへ引っ越しました. 現在はプログラミングの専門学校に通っており, 一年後にエンジニアとして現地就職することを目標としています. 渡航から 1 か月以上経ち生活が落ち着いてきたこのタイミングで, 渡航前・渡航後に行った重要なことをまとめておきます. 将来バンクーバーに引っ越す方の参考になれば幸いです. 筆者のステータス 日本生まれ日本育ち, 大学卒業後 3 年間エンジニアとして働いた後, 海外就職を目標としてバンクーバーに渡航しました. 海外経験は数回の旅行程度で, 海外に特別な縁があったわけではありません. 普通に日本で生まれ育った私の視点から, 海外移住に必要だったことという視点で記事を書きます. 渡航前 最初は海外生活というと現実離れしたことのように思えていましたが, 実際の所必要なものは多くありません. ビザとお金です. それがあればどうにかなりますし, なければどうにもなりません. ビザ 最重要はビザです. ビザとはその国への滞在に必要な許可証のことです. 海外生活においては何よりも重要なものです. 国によって形態は異なりますが, カナダには観光/学生/就労/ワーキングホリデービザなどの種類があります. 自分がどのビザを利用して渡航するかは非常に重要な選択であるため, 情報を集めた上で判断したほうが良いでしょう. 例えばワーキングホリデーは, 強力なものの人生で一度しか使えない切り札のようなビザで, うかつに使ってしまうと後々まで悪影響を及ぼす可能性があります. 私がバンクーバーを選んだ大きな理由の 1 つはビザが取得しやすかったからです. まず学生ビザで渡航し, 一年間学校に通った後, 1 年間就労可能な co-op という制度を使い就職を目指します. その後ワーキングホリデーを使ってさらに 1 年間就労期間を伸ばすこともできますし, 就職できていれば永住権 (≠ 市民権) 取得も見えてきます. もちろんビザの制度が変更される可能性もあるので計画通りに行くとは限りませんが, 今後 3 年間のビジョンが持てるのは悪くないと思っています. 疑問が生じるかも知れないので説明しておくと, エンジニアとしての経験があるにも拘らず学校に通うのは, ビザのためです. 授業で技術に関することを教えてほしいとは, 実はあまり思っていません(傲慢に聞こえるかも知れませんが, まあ多くのことは独学できますし, 授業で教えられることも限られているでしょうし). もちろん一年を無為に過ごすわけではなくその間に就職へ向けた準備をするつもりです. しかし学校に通う最大の目的は co-op とワーキングホリデーで二年間働ける状態を作ることであり, それくらいビザは重要だと考えています. ...

September 4, 2023 · 2 min

『仕組みと使い方がわかる Docker&Kubernetes のきほんのきほん』でようやく Docker の基本を理解する

仕組みと使い方がわかる Docker&Kubernetes のきほんのきほん は Docker の入門書です. イラストやハンズオンが豊富で, サーバや Linux の知識が豊富ではない人にも Docker の基本が分かるように書かれた本です. ネット上のコマンドを見様見真似でなんとなく Docker を使うことは難しくありませんが, 結局そのコマンドはどういう意味なのか, どういう仕組みで Docker が成り立っているのかを知らないと応用できません. これまで docker run や docker-compose up などのコマンドを使ってきたのに, その実何が起きているのか理解していなかったのですが, 本書の説明でようやく基本が理解できました. Docker コマンドのフォーマット Docker コマンドを使う上で最も重要だと感じたのがコマンドのフォーマットです. 1 docker <上位コマンド> <下位コマンド> [オプション] <上位コマンド> は基本的に操作対象を, <下位コマンド> は操作を表しています. 例えば docker container start だと, コンテナを開始するという意味です. これがなぜ重要なのかと言うと, 操作対象を明確に意識できるからです. 自分が操作しようとしているのはコンテナなのかイメージなのかはっきりと分かります. これまで, Docker には, 隔離されたプログラムの実行環境であるコンテナと, コンテナの設計図であるイメージがあるというような説明を目にしたことがあったにも拘らず, それを各コマンドと結び付けられていなかったのですが, このフォーマットを知ることで疑問が氷解しました. コンテナ, イメージ, ネットワーク, ボリュームなど, 扱いたい対象が上位コマンドに来るというただそれだけなのです. 混乱の原因となっていたのは, 上位コマンドは省略可能な場合があることです. 例えば docker ps はコンテナの状態を表示するコマンドですが container の文字がありません. 実はこれは docker container ps と同じ意味なのですが, 歴史的な経緯により ps でも container ps と同じことができます. ちなみに別名もあって, docker container ls も同じです. さらにややこしいのは docker run です. これはコンテナを起動するコマンドなので docker container run と同じ意味なのですが, image pull, container create, container start という 3 つのコマンドの複合です. 操作対象が省略されることがあることに加え, 一つのコマンドが複数の意味を持つ場合があることで混乱が生じていました. ...

May 6, 2023 · 4 min

『達人に学ぶ DB 設計 徹底指南書』でデータベース設計の論理と物理を考える

『達人に学ぶ DB 設計 徹底指南書』 はリレーショナルデータベース (RDB) の設計についての解説書です. 『達人に学ぶ SQL 徹底指南書』 の続編という位置づけのようなので, 本書に登場する SQL が難しいと思ったり, より SQL のことを学びたいと思ったら前作を読むと良いでしょう. 本書ではデータベースの設計を, エンティティの定義や正規化などを行う論理設計と, データ格納の方法や場所を考える物理設計の二段階に分けて説明します. 設計についての基本的な考え方や知識を抑えつつ, やってしまいがちなバッドノウハウや, 論理設計と物理設計のトレードオフと言った実践的な内容にも踏み込みます. 正規化 データベース設計は大きく論理設計と物理設計という二段階に分かれる. 最初に行う論理設計では, 特定の DBMS(Database Management System) や SQL のことは考えずに, プログラムが扱う対象となる物事の属性や物事同士の関係をモデル化する. 論理設計をするに当たって役に立つのが, データの冗長性や非一貫性を排除するための正規化という方法だ. 正規化を理解するには正規化されていないデータを題材にすると分かりやすい. 例えば以下のテーブルは, 都道府県, 市町村, 市町村の規模を表している. このように分割しておけば先に挙げた問題は起きない. 1 2 3 4 5 6 7 8 9 10 +-----------+-----------+-----------+-----------+-----------+--------+ | pref_code | pref | city_code | city | area_code | area | +-----------+-----------+-----------+-----------+-----------+--------+ | 01 | Aomori | 01 | Hirosaki | 01 | Large | | 01 | Aomori | 02 | Hatinohe | 01 | Large | | 01 | Aomori | 03 | Misawa | 03 | Small | | 02 | Yamaguchi | 04 | Ube | 01 | Large | | 02 | Yamaguchi | 05 | Kudamatsu | 02 | Middle | | 02 | Yamaguchi | 06 | Mine | 03 | Small | +-----------+-----------+-----------+-----------+-----------+--------+ このテーブルには 01 Aomori のように何度も登場するデータがあって冗長だ. さらに, データの整合性が取れなくなる場合があるのが大きな問題だ. 例えば 02 Aomori というレコードがあったら, 県コードと県名のどちらを信用すればよいのか. こういった冗長性や非一貫性を排除するためには, テーブルを分割するのが有効だ. ...

May 5, 2023 · 5 min

キャリア 3 年目の振り返り

成果と価値 この一年で, 成果を出すことと仕事の価値を理解することの重要性を学んだ. まず, 営利を目的とする会社組織の一員である以上は成果を出すことが最も重要な役目であることは間違いない. 利益を上げることが目的なのだとすると, 成果は売上の増大かコストの削減に大別される. そのどちらか, あるいは両方に強いインパクトを与える仕事をすることが成果を出すことだ. 成果が重要であると認識しつつ, 大した成果に結びつかない仕事ばかりしてしまうことがある. むしろ, 注意しなければ日々の雑事に埋没するのは簡単なことだ. そうならないようにするためには, 仕事に優先順位を付けて重要なこと, とりわけ重要だが緊急ではないことに取り組む時間を意識的に確保する必要がある. ある仕事が重要かどうか判断するためには, その仕事の価値を理解しなければならない. 仕事の価値は, プロダクトへの理解, ひいては会社が営むビジネスへの理解と考察によって判断できる. 実は, 必ずしも仕事の価値を理解しなくとも成果を出すことはできる. 他人から与えられた仕事をこなすだけなら, 与えられた仕事の重要性を認識している必要はない. しかしそこから先, つまり仕事が所与のものである状態から, 仕事を自発的に見つけ, 他人へ割り振ることができる段階に行くために仕事の価値の理解が必要なのだ. 何をするか自分で決めるのであれば, 自分で仕事の価値を判断しなければならない. そして, 一人で働いているのでなければ周囲にその価値を説明することも必要だ. 価値を説明することで人々も成果を認識できる. プロダクトを理解する, 仕事の価値を判断する, 仕事を提案する. 仕事を完了させ, その価値を説明する. そうやって成果を出す. プロダクトへの理解があって初めて価値判断が可能になり, 価値判断できることでインパクトの大きな成果を狙えるようになる. ミニマリズム, 英語, OSS 最近ミニマリズムにハマっている. と言っても家中の物を処分してがらんとした部屋で暮らしているわけではない. 無駄を排除して重要なものに集中するという考えが気に入っている. それは私生活にも仕事にも活かされていて, 殆どのことは無駄なんじゃないかとか, 今一番大事なことは何だろうかと言うようなことをよく考えるようになった. AI の隆盛と逆を行っているのかもしれないが, やはり英語は重要だと思う. 勉強のために TOEFL を受けたりもした. OSS にコントリビュートしたときもやり取りは英語だったし, そういえば原著で技術書を読んだこともあった. 次の一年 この一年でコンピュータ・アーキテクチャ, 並列処理, SQL を主に学んだ. 引き続き基礎を固める勉強を続けるのだが, それだけでなく何かの分野を深めていく勉強もしたい. 例えばデータベースなら SQL の書き方やテーブル設計はある程度分かってきたので, さらにデータベース内部の仕組みについて勉強すると言ったようなことをイメージしている. OSS は非常に良い経験になったので, 今後より高度な事柄を学んでいくに当たって, 本だけでなく実際のプロジェクトに触れる機会を増やしたい. ...

April 10, 2023 · 1 min

Apache Bench でベンチマークできるミニマルな C 言語製 HTTP サーバ

ab コマンド, つまり Apache HTTP server benchmarking tool をつかってベンチマークできる状態の HTTP サーバを C 言語で作る. なるべくシンプルに必要最小限の要素のみを持ったコードを目指す. 手堅いエンジニアは高速化のために, いきなりコードを書いたりしない. 計測できる環境を整えておかないと, 高速化をしてもその効果を測ることができない. このサーバを出発点として手を加えて (例えばマルチスレッド化したり IO 多重化をしたりして) サーバのパフォーマンスがどのように変化するかを確かめるために使うことを想定している. ソースコード全体は https://github.com/momori256/cs2 にある. ソケット ab を使うには HTTP を解すサーバでなければならないため, まずは TCP での通信を実装する. ソケットプログラミングはお決まりのコードなので説明は省く. いつもお決まりを忘れてしまうので, man getaddrinfo の EXAMPLE をいつも参照している. socket, bind, listen をして accept できるソケットを作成する部分は以下の関数だ. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 int sock_create(const char* const port, int backlog) { typedef struct addrinfo addrinfo; addrinfo hints = {0}; { hints.ai_family = AF_INET; // IPv4. hints.ai_socktype = SOCK_STREAM; // TCP. hints.ai_flags = AI_PASSIVE; // Server. } addrinfo* head; { const int result = getaddrinfo(NULL, port, &hints, &head); if (result) { fprintf(stderr, "getaddrinfo. err[%s]\n", gai_strerror(result)); exit(1); } } int sfd = 0; for (addrinfo* p = head; p != NULL; p = p->ai_next) { sfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (sfd == -1) { continue; } int val = 1; if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { error("setsockopt"); } if (bind(sfd, p->ai_addr, p->ai_addrlen) == -1) { close(sfd); continue; } break; } freeaddrinfo(head); if (!sfd) { error("socket, bind"); } if (listen(sfd, backlog) == -1) { error("listen"); } return sfd; } HTTP リクエストとレスポンス accept して read すればメッセージを受信できる. 動作の確認には telnet のようなプリミティブなツールが役に立つ. ...

February 24, 2023 · 4 min

『Linux と pthreads による マルチスレッドプログラミング入門』で pthreads を実践する

Linux と pthreads による マルチスレッドプログラミング入門 は pthreads の入門書です. 基礎から説明してあるので Linux でのマルチスレッドプログラミングを学びたい方におすすめです. pthreads は知っていましたし, ミューテックスなどのマルチスレッドプログラミングの概念もある程度知っていたのですが, 改めて pthreads で実践してみようと思いました. 必要なもの一通り スレッドの生成と破棄, ミューテックス, 条件変数など, 必要なものは一通り説明されている. 多数ある pthreads の関数から特に重要なものがピックアップされており, 説明も深入りしすぎず手短なので気負わずにさくっと読める. もっと詳しく知りたい場合は man を参照すればよい. というか実際には主だった関数に限っても引数や返り値の意味を覚えられるわけではないので, 結局 man はいつも参照するから, 詳細が省かれていても手間は対して変わらない. 確かこういう関数があったかなぁとぼんやり覚えているくらいで十分だろう. 説明をコンパクトにまとめることも大事である. スレッドプールを実装 本書の後半ではスレッドセーフなキューを実装する. そしてそのキューを使ってスレッドプールを備えた並行サーバを実装する. ミューテックスと条件変数があれば実装はそれほど難しくないだろうと思っていたが, 実際に手を動かして試してみるのは大事だと思う. 事実, ロック絡みで少しハマったりした. Linux の技術書ではソケット関連のサンプルが頻繁に登場するので随分見慣れた. ソケットのプログラムを書くたびに面倒さを感じつつお馴染みのコードを書いている. 動きのあるサンプル CLI のプログラムだとどうしても絵的には退屈になりがちだが, 本書はエンタメ性を意識しているのか面白いサンプルが使われている. 端末上をハエが飛び回るのだ. ハエの数だけスレッドがあり, 並行にハエの位置が計算されている. CLI でのグラフィカルなプログラムを作るために ncurses を使ったことがあったのだが, エスケープシーケンス (printf("\033[2J") で画面クリアなど) でもこれくらいのものが簡単にできると知って感心した. 少し見た目にこだわりたいときはちょうどよいかもしれない. 結語 マルチスレッドプログラミングは難しいと常々思っていますが, 基本的なライブラリを使うのはそれほど難しくありません. できる限りロジックをシンプルにするのが重要だと感じました. コンパクトな本書に倣って記事もコンパクトにしてみました. 本の紹介や学んだことのまとめをするのに毎回長い文章を書く必要はありませんし, 必要最小限はプログラマの美学ですし (ですよね?), たまにはこれくらい短い記事でも良いと思いました. ...

November 22, 2022 · 1 min

C のエレガンスが詰まった『The C Programming Language』

『The C Programming Language』 は C 言語の教科書です. 最新の第二版が出版されたのが 1988 年ですから流石に時代を感じますが, C の原点を知る歴史読み物的な価値があります. 個人的に, 配列やポインタ絡みの異常に複雑な型や typedef などの文法に疑問や不満を持っていたのですが, 本書を読み一部が解消されました. コンパクトな言語 C 言語はコンパクトな言語である. 本書はサンプルプログラムを交えつつ C の文法を解説しているが, 付録を除けば約 160 ページしかない. それでいてプログラムを書くのに必要な機能は一通り揃っているから, 小さいことは良いことであるという UNIX 哲学を体現したような言語だと思う. 本書でよく引き合いに出される Pascal や FORTRAN といった言語が当時は流行っていたのだろうが, 著者の一人である Kernighan は Why Pascal is Not My Favorite Programming Language という論文を書いていたようだし, それらの改良版言語という意味もあるのかもしれない. 今となっては一般的となった概念も, C によってもたらされたものは多いのだろう. 複雑な型の読み方 配列やポインタ絡みでやたらと型の記述が複雑になるが, その読み方を整理しよう. 型を文に翻訳する方法 まずは簡単な型を見てみる. 1 int *x x は int 型の値を指すポインタである. 1 int *x[13] x は int 型の値を指すポインタの配列 (サイズ 13) である. ...

November 6, 2022 · 4 min

『コンピュータの構成と設計 下』でプロセッサのこれからを考える

『コンピュータの構成と設計 MIPS Edition 第 6 版 下』 はコンピュータサイエンスの教科書です. ハードウェアを知り, ソフトウェアを適合させる方法が説明されます. 上下巻に分かれていますが, 内容は完全に上巻の続きです. 各巻で相互に参照されている箇所もあるので, 両方を手元に置いて置くと理解しやすいでしょう. 下巻のメインはメモリ (キャッシュや仮想メモリなど) と並行処理で, アセンブラや論理回路についての付録も含まれています. キャッシュをどのように保存するか考える. キャッシュはメインメモリ中の値を保持するものだから, メモリアドレスに基づいてキャッシュを入れる場所を決定するのは自然だろう. アドレスによってキャッシュの場所を一箇所に定める方法をダイレクトマップ方式という. アドレスが 4bit, キャッシュのブロック数が 4 個なのであれば, アドレス上位の 2bit をインデックスとして用いる. つまりアドレス 0000, 0001, 0010, 0011 は同じインデックスが割り当てられる. 残りの下位 2bit をタグとしてデータと合わせて保持して, 現在キャッシュにあるのがどのアドレスのデータなのか特定できるようにする. もし 0000, 0010 を交互にアクセスするとどうなるだろうか. 両者とも同じインデックスに保存されているためキャッシュ位置が競合し, キャッシュミスが繰り返される. 競合を減らす柔軟な方法はないだろうか. 一つのインデックスに二つのブロックを保存できるようにすればどうだろう. そうすれば二つのブロックを持つセット二つから成るキャッシュができる. 元々 4 * 1 だった構造が 2 * 2 になったということだ. キャッシュを格納するとき, 各セットにある二つのブロックどちらを使っても良い.もちろん空きがなければ追い出すしかなく, LRU(Least Recently Used) 法などに従って捨てるキャッシュを選び, 新たにキャッシュを入れる. 一般化して, 一つのインデックスに複数のブロックを保存する方法をセット・アソシエイティブ方式という. 究極はセットが一つしかないフル・アソシエイティブ方式だ. 一セット当たりのブロック数のこと指す連想度という用語を使えば, ダイレクトマップ方式からフル・アソシエイティブ方式に向けて連想度が上がると表現できる. ...

October 20, 2022 · 3 min

『コンピュータの構成と設計 上』でソフトとハードを股に掛ける

『コンピュータの構成と設計 MIPS Edition 第 6 版 上』 はコンピュータ・アーキテクチャの教科書です. 2 名の著者パターソン&ヘネシーの名前を取ってパタへネという愛称で知られています. ヘネパタという紛らわしい愛称が付けられている『コンピュータ・アーキテクチャ』はより上級者向けの内容です. 本書はソフトウェアとハードウェアの境界付近についての本です. コンピュータの中核的な仕組みを説明し, プログラムを書く上でどうやってハードウェアを活用すればよいかという視点で語られます. コンピュータの中身を知りたい方におすすめです. Moore の法則の終わり プロセッサは数百ものトランジスタが搭載された集積回路によって実現されている. トランジスタを始めとする半導体素子の材料になるのはシリコンという砂に含まれている物質だ. 円柱状のシリコン結晶を 0.1mm ほどに薄くスライスしたウェハ (wafer) を格子状にカットすると, 小さなチップができる. チップ一つ当たりのトランジスタ数が 2 年で倍増するという, Intel の創始者の一人である Gordon Moore の予想「Moore の法則」は 50 年間に渡って正しかった. しかしいつまでも指数的な成長が続くわけではない. 消費電力の増加とともに発熱が増え, ついには冷却性能の限界を迎えたのだ. ここに来てプロセッサ開発者は方針転換を余儀なくされた. 一つのプロセッサの性能が頭打ちとなったので, 一つの CPU に複数のプロセッサを搭載することにしたのである. マルチコア CPU の性能を引き出すにはプログラムの努力が欠かせない. 現代は, ソフトウェアエンジニアもハードのことを考えなければならない時代なのである. MIPS について 本書で取り扱われる MIPS という命令セットは, 命令数を抑えシンプルさを重視して設計された. フォーマットが単純であれば規則性が保たれ, 回路の実装が容易となる. そして単純な回路は消費電力を抑えらる. スマートフォンの時代 (ポスト PC 時代) において, 消費電力は命令セットの良し悪しを決める鍵となった. MIPS と同様の思想を持って設計された ARMv8 や RISC-V が脚光を浴びるのは自然な流れであった. ...

October 5, 2022 · 2 min

『入門 UNIX シェルプログラミング』で UNIX の世界を学ぶ

『入門 UNIX シェルプログラミング シェルの基礎から学ぶ UNIX の世界』 は UNIX シェルプログラミングの入門書です. 良いと思ったのは網羅的で実用的なところです. おそらく一通りの基礎的なトピックスに触れていて, 本書を読んでおけば大抵のことには対応できる土台が身に付くと感じました. 基礎だけにとどまらず, 豊富な実例を伴った解説がなされるので, 辞書やクックブックとしても使えそうです. 基本的だけど知らなかったこと 検索しづらいようなトピックスがきちんと紹介されているのが嬉しいポイントです. これまで何となく知っているけどよく分からずにいたことが分かって, 知りたいことが知れたという気分がしました. #/bin/sh とは何か シェルスクリプトの最初の行に書くシェバンというものですが, これはスクリプトを実行するのインタープリタを指定する記述です. シェバンがなければ余計な手順が掛かり, 意図したのとは異なるシェルでスクリプトが実行される可能性があります. シェルはまず exec システムコールでコマンド実行を試みますが, シェルスクリプトは実行ファイルではないので exec は失敗します. 次にファイルに実行権限があればシェルスクリプトだと判定し, 現在のシェルでスクリプトを実行します. 余計な手間を省く, 実行されるシェルを統一するという役割があるのです. そういうわけなので, スクリプトとして実行されないファイルであればシェバンは不要です. 例えば関数を定義してドットコマンド . で読み込んで使うファイルの場合です. ドットコマンド . ファイルの内容を展開するコマンドです. 例えば . abc とするとファイル abc の内容が実行されます. C 言語の #include のようなものですね. 用途としては, 関数を定義しておいたり, 環境変数を設定したりするのに便利です. こういう記号はネットでは検索しづらいので本に書いてあると助かります. 教科書的な本を読む利点だと思います. ワイルドカード ls ~/* でホームディレクトリ以下の全てのファイルが見られますが, これはワイルドカードという機能の一部です. 以下のような記号でファイルを指定できます. * : 任意の文字列 ? : 任意の 1 文字 [ABC]: A/B/C のいずれかの文字 [!ABC]: A/B/C 文字の文字 よって echo * とすれば ls と同じ効果が得られます. もちろん ls [!0-9][a-zA-Z]??* のように組み合わせて使うこともできます. ...

September 7, 2022 · 3 min