Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

就活を振り返る

2018年(学部3年) 4月 院進以外に、就職という道があると気がつく(院には当然進むものだと思いこんでいた)

5月 院進と就職で悩み始める

6月 就職しようと決める

〜12月 「自己分析」とか「業界研究」とか何すればいいか分からないし、部活が忙しくてやる暇がない

1月 近所でやってたインターンや説明会に参加する

2月 就活を始める。

企業ホームページの採用情報のところから直接応募するスタイルを取った。就活サイトに登録したり、説明会に参加したりしていなかったため、手当たりしだい応募する形になった。

  • C社 課題選考通る→一次面接を受ける→お祈り
  • P社 書類選考すら通らず
  • C社 選考通る→いつまでもメールが返ってこなかったので東京から帰る途中に「面接は明日いかがですか?」来る→無理だったので断る
  • C社 ウェブテスト受ける→一次選考→お祈り
  • D社 一次面接(Google Hangout)を受ける→二次面接へ→お祈り
  • H社 書類選考通る→一次面接(ウェブ面接)を受ける→最終選考を受ける→お祈り
  • L社 課題選考を受ける→一次面接(現地)を受ける→最終面接へ→内定!
  • Y社 課題選考に通る→適性検査→一次面接へ

雑感

課題選考はとりあえず通るので、最低限は技術力を評価されていたと思います。しかし、とにかく面接が通りませんでした。後でも書きますが、チームで開発したことがなくて、どういうふうに働くか具体的なイメージができなかったのが要因の一つだったと思います。

最終的に、受けた中で一番年収が高い企業になりました。労働条件もとてもいいので嬉しい限りです。ただ、その環境を享受できるほど能力がある自信がないので非常に不安です。というか周りのレベルについていけるのでしょうか…?がんばります。

面接でたびたび「どういうふうにして情報を仕入れていますか?(技術系の流行の追い方みたいな意味だったと思う)」と聞かれたのが印象的でした。

「Linuxカーネルの役割をカンタンにいくつか挙げてみて」と言われて出てこなかったのが悔しかったです。プロセス管理とかメモリ管理とか分かるけど、それが「カーネル」という言葉と結びついていませんでした()。授業でもやりましたし、応用情報の勉強でもやっていてそのへんの知識はあっただけに、惜しいことをしました・・・

よく聞かれたこと

  • 「将来的にどういうエンジニアを目指しているか?」
  • 「チームで開発したことはあるか?」(これはメチャクチャ聞かれた!!)
  • 「チームで働くとき、どうチームに貢献できるか?」

後悔したこと

チーム開発の経験についてほぼ毎回聞かれましたが、インターンやアルバイトなどに行っていなかったため毎回困りました。開発型のインターンに行っておくと有利かもしれません。インターンに参加しておけば、実際にチーム開発を経験できるので、チーム開発に向いていないのにプログラマになってしまう事故を防げます。

他に、自己分析をしていなかった…というかやり方が分からなかったのは良くありませんでした。自己分析をすることで、自分に合う環境を探す指標が作れるので、「何が好きか」「どう働きたいか」「何が嫌か」「どういう福利厚生が欲しいか」などをまとめるだけでもだいぶ違ったんじゃないかと思います。

ポートフォリオ

就活しているのでブログにもポートフォリオを書いておきます。

自己紹介

名前はクロパンダです。

現在は東北大学の工学部で情報工学を学んでいます。学部4年生なので、まだ研究は始まっていません。

趣味はプログラミングと合気道です。プログラミングは中学生から、合気道は大学から始めました。

主にJavaScriptを書いています。今までに作ったもの・書いたものとして以下が挙げられます。

制作物

  • unitaryjs 宣言的に書けるCanvasライブラリ
  • Paper Memo ブラウザ上で紙のUIを再現するメモサービス
  • 炎上

ほかにもあるのでサイトの制作物一覧をご覧ください。

unitaryjs

HTML5のCanvasは「線を引く」「円を描く」のような命令ベースでプログラムを書かなければなりません。これではコードを読んでもどういう図形を書こうとしているのかがわかりません。そこで、「四角形を描く」「多角形を描く」「5本の線分で星を描く」といった風に宣言的に書けるようにするライブラリを作りました。Qiitaに投稿したところ、52いいねを頂けました。

Paper Memo

ページ上の任意の箇所に入力フォームが設置できるサービスです。テキストファイルは1次元方向(横方向)にしか文字を設置できず、紙のような自由度がなくて使いづらいと思ったのが動機でつくりました。紙のような自由度、キーボードによる入力のしやすさを組み合わせたサービスです。

技術的に(自分としては)新しいことにたくさん取り組みました。たとえば、バックエンドでGoを使い、GraphQLのリクエストをさばいています。また、今までRDBMSしか触ってこなかったのでNoSQLのMongoDBを使ってみました。

ほかにもReact + TypeScript + Redux + immerでフロントエンドを書いたり、メールサーバーを建ててアクティベートメールを送信したり、ソーシャルログインを実装したり(これはまだ未完成)といったことをしました。

これは「新技術を試してみたい」と「こういうサービスを作りたい」というタイミングがマッチして作ったサービスです。サービスをつくるときは「新技術を試したい」という動機で作ることが多いのでめずらしいパターンでした。

炎上

これはWebSocketの習作として作ったミニゲームです。アクセスしているユーザーは「火を起こす」か「薪を足す」ことができます。そして、アクセスしている人みんなで火を絶やさず燃やし続けようというゲームです。誰かが「火を起こす」か「薪を足」したらサーバーから通知が送信され、画面が更新されます。

こっちは「WebSocketを試したい!」という理由だけでつくりました。「薪を燃やしてぇッッ!!」みたいな動機はありません。上でも書きましたが、「新技術を試したい」という動機でサービスを作ることが多く、これはその最たる例です。

webpack.config.jsのプラクティスを考えてみた

何度もwebpack.config.jsを手書きしていて面倒くさくなってきたので、ここに書き方を残しておきます。

webpack.config.jsを書く際によく使うTipsとして、これらが挙げられます。

  • mode: env.mode || 'development'
  • path.resolve(__dirname, path_to_file)を使う
  • options.resolve.extensionsに読み込みたいファイルの拡張子を記述
  • entryを複数書くとoptions.output.filename'[name].min.js'のように指定できる
  • loaderはoptiopns.module.rulesに書き込む

ひとまずテンプレ

最初にwebpack.config.jsのテンプレを載せておきます。どうせ未来の僕がこの記事を読むときは、このテンプレを見たいときだけなので。

const path = require('path');

module.exports = (argv, env) => ({
    mode: env.mode || 'development',
    entry: path.resolve(__dirname, './src/main.js'),
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
    },
    module: {
        rules: [],
    },
});

記事の後半の内容が必要そうなら使うバージョン。

const path = require('path');

module.exports = (argv, env) => ({
    mode: env.mode || 'development',
    entry: path.resolve(__dirname, './src/main.js'),
    // entry: {
    //     main: path.resolve(__dirname, './src/js/main.js'),
    //     index: path.resolve(__dirname, './src/js/index.js'),
    //     gallery: path.resolve(__dirname, './src/js/gallery.js'),
    // },
    // resolve: {
    //     extensions: ['.js'],
    // },
    output: {
        // filename: '[name].min.js',
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
    },
    module: {
        rules: [
            // {
            //     test: /\.css$/,
            //     use: ['to-string-loader', 'css-loader'],
            // },
        ],
    },
});

mode: env.mode || 'development'

この設定をしておくと、package.json内で開発ビルドとプロダクションビルドをカンタンに切り替えることができます。

  "scripts": {
    "build": "webpack --mode production",
    "build:dev": "webpack",
    ...
  },

応用として、options.output.filenameを書き換えることもできます。

{
    output: {
        filename: env.mode == 'production' ? 'bundle.min.js' : 'bundle.js'
    }
}

path.resolveを使う

pathモジュールのpath.resolveメソッドを使ってファイルパスを指定するようにします。例えばoptions.entryoptions.output.pathなどで使うといいです。

なぜわざわざpath.resolveを使うかという理由は webpack.config.jsで思ったpath.resolveって何のためにあるの?に書いてあります。

Windowsとかだとパス区切りが/じゃないこともあるみたい。バックスラッシュっていうやつ(\)。だから__dirname + '/src'だとパスがおかしくなってしまうことがあるからpath.resolveを使って安心安全で行こうぜ!ってことらしい。 (引用: webpack.config.jsで思ったpath.resolveって何のためにあるの?)

環境間の差異を吸収する目的のようです。

読み込みたいファイルの拡張子はoptions.resolve.extensions に

よく忘れるので書いただけです。特に解説することはないです。

entryが複数あるときのoutput.filenameの書き方

これはそこまで頻度高くないです。

{
    entry: {
        main: path.resolve(__dirname, './src/main.js'),
        sub1: path.resolve(__dirname, './src/sub1.js'),
        sub2: path.resolve(__dirname, './src/sub2.js'),
    },
    output: {
        filename: '[name].bundle.js'
    }
}

loaderは optiopns.module.rules に書き込む

めちゃくちゃ当たり前なんですが、手書きすると「あれ?どこに書くんだっけ?」となるので書いておきます。

参考

webpack.config.jsで思ったpath.resolveって何のためにあるの?

はてなブログのHTTPS化をするとJSBinの埋め込みが無効化されるので注意

JSBinの埋め込みは便利ですが、HTTPSのサイトに埋め込むにはJSBinの有料会員登録をしなければなりません。なので、JSBinを使ってコードを埋め込んでいる場合、注意してください。

JSON5ならケツカンマができる!

JSONでケツカンマがあったらなあ、コメントを入れられたらなぁと思うことありませんか?僕はpackage.json内のnpm scriptsをいじっているときに頻繁に思います。

そんな我々の思いを受けてできたプロジェクトがあります。その名もJSON5です。今回はこれを紹介したいと思います。

JSON5とは?

JSON5とは様々な仕様が追加されたJSONのスーパーセットです。たとえば以下のような仕様が追加されます。

  • 配列・オブジェクトのケツカンマ
  • シングルクォートによる文字列
  • 単行・複数行のコメント
  • 16進法による数値表記

JSON5でのパース・符号化

npmでインストールするか、scriptファイルを読み込むことで使えます。

$ npm install json5
<script src="https://unpkg.com/json5@^2.0.0/dist/index.min.js"></script>

パースも符号化もJSONとほとんど同様です。

JSON5.parse(json5string);
JSON5.stringify(object);

JSON5.stringify()では、文字列をクォートで囲むか指定できる以外はほぼJSON.stringify()と変わらないようです。

どこで使われているか

JSON5に依存しているnpmパッケージを見てみると、@babel/corevueifyparcelなどが対応しているようです。

ちなみにtsconfig.jsonでもケツカンマができますが、JSON5をサポートしているのではなく、設定ファイルを読み込むときに独自のJSONパーサーを使っているためだそうです(参考: tsconfig.json isn't strict JSON, what now? : typescript)。

参考