yikegaya’s blog

仕事関連(Webエンジニア)と資産運用について書いてます

Rust + WebAssemblyのDocker開発環境構築メモ

Mozillaチュートリアルを参考にRustとWebAssemblyの開発環境を構築したんですが割とハマりました。作業内容書き残してみます。

以下のページを参考にしています。Rustで実装したWasmをコンパイルしてnpmとwebpackで配信するチュートリアルです。

developer.mozilla.org

上記のサイトではプロジェクト名はhello-wasmとしていますが今回はこの後ブラウザで作るテトリスを実装する予定なのでプロジェクト名は「rust-tetris」としています

Dockerfile

参考にしたページではDockerは使わずホストに環境構築する内容だったんですが自分のPCにはいろいろとプロジェクトが載っていてホストでバージョン管理などするのが面倒だったのでDockerで構築しました。

できたDockerfile

# 言語はrustとnode.jsが必要なんですが今回ベースイメージはrustにしてみました。
# またrustはまだ言語そのものやライブラリなど周辺環境の開発が盛んな印象があるのでlastestで指定せずにVer1.77を指定しています。
FROM rust:1.77

WORKDIR /app
COPY . .

# nodeとnpmのinstall
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
RUN apt-get install -y nodejs
RUN npm install -g npm@10.5.0

# WebAssembly開発に必要なwasm-packのinstall
RUN cargo install wasm-pack
# なくてもいいですがリンタのinstall
RUN rustup component add rustfmt

# webpackのbuild
WORKDIR /app/site
RUN npx webpack

docker-composeも作りました。 コンテナ1つ作るだけなのでdockerコマンドだけでも開発できそうですがvolume作ったりport指定するのにオプションが長くなっちゃうので作っといた方が開発しやすいかと思います。

version: '3.8'

services:
  tetris:
    build:
      context: .
    working_dir: /app/site
    command: ["npm", "run", "serve"]
    # 3000とか8080は別のプロジェクトで使ってたので適当に空いてるポートを割り当て
    ports:
      - 3456:8080
    volumes:
      - .:/app      
      - cargo-cache:/usr/local/cargo/registry
      - target-cache:/app/target
      - cargo-bin:/usr/local/cargo/bin

volumes:
  cargo-cache:
  target-cache:
  cargo-bin:

WebAssembly環境の構築

フォルダ構成

上記のDocker環境にWebAssemlyとWebpackの環境を作っていくわけですがフォルダ構成は次のようになりました。

 /app
  │
  ├── Cargo.lock
  ├── Cargo.toml
  ├── Dockerfile
  ├── README.md
  ├── docker-compose.yml
  ├── pkg // WebAssemlyのbuild先
  │   
  ├── site // npm、webpack関連
  │   ├── dist // webpackのbuild結果出力先
  │   ├── index.js
  │   ├── index.html
  │   ├── node_modules
  │   ├── package-lock.json
  │   ├── package.json
  │   └── webpack.config.js
  │   
  ├── src
  │   └── lib.rs // WebAssemlyの実装
  │   
  └── target

RustでのWebAssemblyコード実装

チュートリアルのコードそのままです。ページを開いた時にalertを表示します。

wasm-bindgenというツールを使ってjavascriptとRustのコードを繋いでいます。

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}

プロジェクトルートで以下のコマンドを実行するとnpmで使えるようコンパイルできます。 --target bundlerオプションでwebpackのようなbundlerで実行できる形式への変換できます。

wasm-pack build --target bundler

実行するとpkgフォルダ以下にjavascriptとtypescriptのコードとpackage.json、READMEが出力されます。

root@1d9867bd702a:/app# ls -l pkg
total 44
-rw-r--r-- 1 root root   520 Mar 28 06:08 README.md
-rw-r--r-- 1 root root   516 Mar 28 06:08 package.json
-rw-r--r-- 1 root root   115 Mar 28 06:08 rust_tetris.d.ts
-rw-r--r-- 1 root root   160 Mar 28 06:08 rust_tetris.js
-rw-r--r-- 1 root root  2553 Mar 28 06:08 rust_tetris_bg.js
-rw-r--r-- 1 root root 16843 Mar 28 06:08 rust_tetris_bg.wasm
-rw-r--r-- 1 root root   287 Mar 28 06:08 rust_tetris_bg.wasm.d.ts

build後にnpm linkコマンドを実行してwasmのコードをグローバルなnpmリポジトリにリンクさせます。 ここのコマンド実行もdockerコンテナ作成時に組み込んだ方がいいかもしれませんが一旦コンテナのシェルにattachして実行してます。

docker exec -it tetris_tetris_1 bash
cd /app/pkg
npm link

Webpack実行環境構築

/app/siteにwebpackとnpmでhtml、jsを配布する環境を作ります。

まず先ほどグローバルnpmリポジトリにリンクしたパッケージを/app/siteフォルダにインストールします。

cd site
npm link rust-tetris

package.json

次にpackage.jsonを作成します。今回は以下のように書きました

{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "dependencies": {
    "rust-tetris": "^0.1.0"
  },
  "devDependencies": {
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^5.00"
  }
}

チュートリアルのpackage.jsonは以下のようになっており現時点でのwebpackのバージョンが古いのですが今回は5系のバージョンをインストールしてみました。

またwebpack-cliとwebpack-dev-serverを指定すれば依存関係でwebpackも入るんじゃないかと思って端折ってみてますがそれで問題なさそうです。

{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "dependencies": {
    "hello-wasm": "^0.1.0"
  },
  "devDependencies": {
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

package.jsonを作成した状態でnpm installを実行するとwebpack関連のライブラリが/app/site/node_modules以下にインストールされます。

webpack.config.json

次にwebpack.config.jsを記述します。

const path = require("path");
module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  mode: "development",
};

チュートリアルでは上記のようになっていますが、webpack5ではdevserverのstaticとasyncWebAssemblyの指定がないとエラーが発生するようです。

設定を追加したwebpack5向けのconfigは次の通りです。

const path = require('path');

module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js", // index.jsよりもbundle結果のjsであることがわかりやすいので命名変えてます
  },
  devServer: {
    port: 8080,
    // 追加
    static: {
      directory: "./",
    },
  },
  // 追加
  experiments: {
    asyncWebAssembly: true,
  },
};

index.htmlとindex.js

あとはwebpackから配布されるindex.htmlとhtmlから呼び出されるwasmを実行するjsを用意して完了です。

index.html

<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <h1>hello-wasm example</h1>
    <script src="./dist/bundle.js"></script>
  </body>
</html>

index.js

import("./node_modules/hello-wasm/hello_wasm.js").then((js) => {
  js.greet("WebAssembly with npm");
});

エンジニア転職活動時に面接で聞かれたことメモ

フリーランスのWebエンジニアとして4年間活動してきましたがぼちぼち正社員に戻るのもいいかなと思い、1月末ごろから3月頭にかけて就活してみました。

誰かしらの役に立つかもしれないので面接で聞かれたこと書き残してみます。

転職先を決める際の応募基準

自分の経歴・スキル、フリーランスをやめようと思った理由、応募先を決める際の基準などは以前に別のブログに書きました。

ikeyu0806.hatenablog.com

面接で聞かれたこと

記憶している限り箇条書きで書きます

技術的な質問

  • あなたが今から担当をお願いしようとしているクラウドサービスを実装する場合、どういった技術やアーキテクチャを選びますか?
  • あなたが今からTwitterを作るのであればどういったどういった技術やアーキテクチャを選びますか?
  • Webサービスのパフォーマンスチューニングをする際はどうする?
  • TCP、IPについて説明してください
  • TCPUDPについて説明してください
  • マルチスレッドプログラミングについて説明してください
  • 仮想OSについて説明してください
  • ReactとVueどっちが好き?
  • 動的型付け言語と静的型付け言語どっちが好き?
  • マイクロサービスのメリット、デメリットは?
  • モノリス、モジュラモノリス、マイクロサービスの選定基準は?
  • 今までrails new何回した?
  • 使ってみてよかったgemは?

その他の質問

  • 今後のキャリアプラン
  • テックリードとプロダクトマネージャでは自分ではどっちに適性があると思う?
  • スタートアップで細かいマネジメントはできないが自走できる?
  • リリースされて長い年月が経っているシステムの保守運用は嫌ではない?
  • 今まで最も印象に残っているプロジェクトは?
  • 今まで最も苦労したプロジェクトは?
  • 今まで最も楽しかったプロジェクトは?
  • 今まで最も成長を感じたプロジェクトは?
  • 応募先を決める際の基準は?
  • なぜフリーランスを辞めようと思ったか。
  • 入社したらどんな貢献ができる?
  • 文系学部卒業だがエンジニアになった理由は?
  • 会社のビジョンに共感できそう?
  • 尊敬するエンジニアは?理想像は?

以上です

NVIDIA製GPUの周辺ソフトウェアとコミュニティを調べてみた

Rebuildfm聴いてたらNVIDIAの決算の話題があり、GPUそのものだけでなくサポートやコミュニティがあるので強い。的な話をされており気になったのでソフトウェア開発やコミュニティなどNVIDIAGPUの周辺事情について調べてみました。 rebuild.fm

NVIDIAの提供するソフトウェア

CUDA

2006年からCUDAというコンパイラやライブラリを含んだCPUプログラミングの開発プラットフォームを提供しておりここに依存したエコシステムが出来上がっているようです。物理的にGPUを開発しても付随するソフトウェアがないと開発ができないのでCUDAを開発していることはかなり強みということなんだと思います。

OSSプロジェクト

NVIDIAgithub見に行ったらこれ書いてる時点で418レポジトリあって思ってたよりプロジェクト多かったです。

ザッと見ですがOSカーネルサポートやメトリックス計測のライブラリのみならずGPU市場を盛り上げるためかAIや動画教材を提供してたりKubernetesやSparkなど現状のソフトウェア開発でよく使われているライブラリのサポートも対応しており抜かりないな、という印象です。

プロジェクトの例

github.com

コミュニティ

開発者、研究者、AIや動画に関連した企業のビジネスサイド担当者、学生など各方面にセッションやチュートリアル、ワークショップを提供していてこれも抜かりなさそう。

www.nvidia.com

GPU市場でNVIDIAのシェア

2023年時点で92%らしいです。2番手がAMDみたいですがほぼほぼ一強状態。 www.sbbit.jp

2番手のAMDも同じようにソフトウェアサポートしてますがザッと見NVIDIAほど充実はしてなさそう。 github.com

NVIDIAの株買うべき?

NVIDIAは業績が右肩上がりで株買っとけば儲かるんじゃないかと当然考えますがどうなんでしょう。

調べた限りGPUそのものの出来の良さだけでなく周辺ソフトウェアやコミュニティの充実度が高いので他企業に出し抜かれるリスクが低そうだしまだ上がり続ける、というポジティブな見方もできればこの辺りでもうほぼ株価天井だろう、というネガティブな見方もできるんですが正直わからんです。

他企業に出し抜かれるリスクは低そうなので買って大損することはないと思うんですが、個別株で他の人を出し抜いて大儲けするんであれば逆張りした方がいいと思うんですが、株価上がり続けてて半導体業界よくわかってない一般層にまで注目される企業になった今だとローリスクローリターンな株なのでは?と感じており(投資素人の知識ですが)

現状ではローリスクで堅実に資産形成するならインデックス積み立ててくでいいかなという自分としてはの判断で買わないことにしてます。

ビットコインとイーサリアム換金してみた & 資産運用について

コインチェックというアプリで買ったビットコインイーサリアムを換金してみました。

1月にビットコインイーサリアムをそれぞれ10万買ってニュースとか読むにビットコイン上がりそうだったんで2月に40万買い足して合計60万買ってました。

で、今月ビットコイン62万2840円、イーサリアム15万3200円で換金したんで17万6040円儲かった形にはなりました。税務申告はするので税金で大分引かれると思いますが。

勉強&話のネタになるかなと思って手を出してみたんですが需要と供給のみで価格が上がったり下がったりして動きの読み方が今のところよくわからず2ヶ月くらい毎日チャート眺めてなんとなく気が済んだんで換金しちゃいました。

米国で仮想通貨ETFが承認されたとかロシア人の持ってるドル資産が一部戦争で価値がなくなって資産の置き場所として仮想通貨が注目されてるとか諸々景気の良さそうな話もあればマイニングで膨大なエネルギーを使うので環境に悪いとか犯罪者の資金洗浄に使われてるとかのマイナスな情報もあればで結局のところ今後どうなるかはっきりとはよくわからず、現状では仮想通貨はパチンコとか競馬みたいなもんかなと思ってます。

資産運用としてはS&P500とかTOPIXとか全世界株に回した方が着実に上がるしリスクも世界恐慌とか世界大戦レベルの事件が起きなければOKそうだしNISAとiDeCo使えばある程度非課税だし課税されても20%で雑所得扱いの仮想通貨より安いしでやっぱ資産はそういったインデックス投資信託に置いとくでいいかなと個人的には思ってます。

ただ投資信託は買って置いとくだけで面白くないので緊張感が欲しい人は仮想通貨いいかもです。

Webエンジニア転職の時に応募する会社の基準書いてみる

2020年からフリーランスとして活動しているんですがぼちぼちWebエンジニアとしての力量にも自信がついてきて「もう少し裁量のある仕事がしたい」と思い始め正社員での転職活動を始めてます。

フリーランスだと「開発会議でこの機能欲しいって話が出たんだけど作ってください」みたいに依頼が来てなんで作るのかよく分からず実装だけする。みたいな仕事が多いんですがちょっと飽きてきたので。

で、面談でよく聞かれる「会社を選ぶ際のポイントはなんですか」みたいな質問への返しをまとめてみます。

自分のエンジニアとしてのステータス

書く前にまず自分のエンジニア歴です。

  • 2024年2月現在エンジニア経験8年ほど
  • WebエンジニアとしてRuby on Rails、Go、React、Vue、AWSなどの実務経験あり。
    • バックエンド、フロントエンド、インフラの開発業務は一通り全部できる自信あり

経験値やスキルセットが違えばエンジニアでもまた違った応募基準になるのだろうとは思ったりはします。

転職時に見てるポイント箇条書き

  • 会社のビジョンに共感できるか、プロダクトに愛着を持てそうか
  • フロントがVue or React
  • 希望年収を満たしている
  • 開発/デプロイ環境がdocker(マストではない)
  • アジャイルスクラム開発を実践している
  • いろんな仕事ができる(バックエンド実装だけ、Railsだけとかではない)
  • 週に何日かはリモートできる
  • 部門間の縦割りが激しくない、官僚主義的な組織になっていない
  • テストコードを書いている。もしくはこれから書かせてくれる

エンジニアとしての開発環境の具体的な話です。

詳しく書いてみます。

会社のビジョンに共感できるか、プロダクトに愛着を持てそうか

これはまあ、当然重視します

フロントがVue or React

Railsのerbのようなテンプレートエンジンで開発するよりもReactもしくはVueを使っている方が実装しやすいですしモダンな環境で開発できる方がモチベが上がるので。

希望年収を満たしている

年収は大事

開発/デプロイ環境がdocker

dockerは正直マストではないですがローカル開発環境で使うミドルウェアMySQL、Postgre、Redis、ElasticSearchなど)が多かったりとホストでの環境構築の難易度が高いプロジェクトではdockerで開発したいです。

Webフロントのプロジェクトなんかは立ち上げるプロセスがnodeだけだったりするので別に無理にDocker使わなくても良いなどはあると思います。

デプロイ環境もdocker使った方が運用ラクだと思っているのですがまあ、これはそこまで強いこだわりではないです。

アジャイルスクラム開発を実践している

これは大事。ウォーターフォールやオレオレ開発手法を取っている職場は地雷の可能性が高いと思ってます。

いろんな仕事ができる(バックエンド実装だけ、Railsだけとかではない)

これまでバックエンド実装、Webフロントエンド実装、AWSでのインフラ構築・運用を業務で経験してきて業後や休みの日にもそれぞれ結構な学習リソース割いてきたのでこれらの知識、経験を生かせる仕事がしたいと思ってます。

週に何日かはリモートできる

エンジニアの仕事はコーディングの割合が多いので毎日出社は必要ないと思ってます。

部門間の縦割りが激しくない、官僚主義的な組織になっていない

組織の闇みたいなものがなるべくないことは重要だと思ってます。一部の人が仕様や社内事情をホールドして社内のポジショニングに使ってたりとか社内の問題を「他の部署の問題でしょ」みたいに責任転嫁する傾向にあるなど。

テストコードを書いている。もしくはこれから書かせてくれる

テストコードがないとデプロイ前にスプレットシートにテスト項目を書いて手動チェックして、、みたいな面倒な手作業が増えるのでこれも大事だと思います。

以上

とりあえず思いつく限りはこんなところです

Github Copilotを使ってみた感想箇条書き

今の職場がお試しでGithub Copilitを契約しており何人かテストユーザを募集していたので応募して使ってみました。

docs.github.com

エディタはVSCode。開発に使った言語、フレームワークはGo Typescript Vue Nuxtです。

使ってみての感想箇条書き

職場に報告するためにまとめた感想です。公開して問題があるような内容でもないのでここでも書いてみます。

よい点

  • Goだと構造体をレシーバとしたメソッドを追加する場合にinterfaceにメソッドを追加する必要があり、それが地味に面倒で対応が漏れがちだがCopilotを使うと自動で補完してくれるのでその分の作業量が減る
  • またライブラリのimport漏れでのコンパイルエラーも地味に多いが自動で不足しているものを提案して補完してくれるのは便利
  • コードを途中まで書くと「残りはこんなですよね」みたいにサジェストしてそれが正しい場合タブで承認していけば実装が進むのでタイピング量は減っている実感があり結果時短になっている
  • 同じような変更を大量のファイルで繰り返す場合は自動で変更内容を提案してくれるのがありがたい。いろんなファイルからimportされている共通ライブラリのメソッドの仕様が変わった時など

いまいちな点

  • ある程度書いてからの自動補完はいい感じだが空のファイルでのコメントからの0→1のコード生成はうまく使えなかった
  • 地味にライブラリのimport先を間違えたりタイポした変数名を提案してくることがある

使うべき?

月4000円なのである程度のスキルのエンジニアの時給が4000円以上であることを考えると企業側としては契約して社員に配布するのはありだと思います。

ただ個人として契約する気には今のところならないです。

新NISA口座作って投資信託200万ほど買ってみた&積み立て設定してみた

投資全くやってなかったけど新NISAが話題になって周りの声を聞いてもやらねば損な感じだったので色々調べて投資信託200万ほど購入して積み立てNISAも設定してみました。

口座解説

NISA口座は三菱UFJスマホアプリから簡単に解説できたのでそこで作っちゃいました。 購入も三菱UFJ銀行のアプリからポチった。

買ったもの

とりあえず本屋でNISAについて書いてある雑誌2冊かってググったりして調べて以下の投資信託50万ずつ買ってみました。

  • eMAXIS Slim 全世界株式(オール・カントリー)
  • eMAXIS Slim 米国株式(S&P500)
  • eMAXIS Slim 国内株式(TOPIX
  • ニッセイ外国株式インデックスファンド

調べた感じeMAXIS Slim 全世界株式(オール・カントリー)が一番無難で人気っぽいですが勉強がてら分散して買ってみてます。 eMAXIS Slimシリーズが良さそうだったんですが1つだけ勉強がてら違う商品にしてみている。

あと全世界株式と米国株式に毎月5万ずつ積み立て設定してみました。

しばらくほっといてどうなるか観察してみます。10年、20年、30年とほったらかしておく予定です。