試して理解 Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識 を読んだ

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

発売されたときに買って積んでしまっていたのを今更読んだ。

感想

「試して理解」とタイトルに入っているように、実際にCでプログラムを書いたり、ターミナルからコマンドをうってLinuxの挙動を実験しながら、Linuxがどう動いているかを理解していく進めかたになっている。さすがにエンジニアになって何年もたつので「全くしらないことばかりだった」みたいなことはないけど、プロセススケジューラ・仮想記憶など知識として知っているレベルだったことも、実際にプログラムを書いて挙動を確認すると理解が深まってよかった。WEBエンジニアとしてこのレイヤーのことを意識することはそんなに多くないと思っていたものの、ちゃんと手を動かして挙動を確かめてみると自分が気づいていなかっただけでこのレイヤーのことをもっと深く知っていれば仕事でヒントになる場面は結構あったのではという気がした。

Linux環境は仮想環境などは使わずにマシン上にLinuxを立ててくれ〜とあったけど、マシンを用意するのが面倒だったのでParallel上にUbuntu立ててやりました。デバイス絡むところはさすがに難しいけど、それ以外の部分は概ね問題なくできたと思う。

自分は出てすぐ買ったので初版なんだけど、結構誤植があるようなのでこれから読む人はサポートページを確認しましょう。

gihyo.jp

次はGoならわかるシステムプログラミングを読もうと思っている。前職で輪読回やってた気がするので出ればよかったな〜

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

  • 作者:渋川 よしき
  • 出版社/メーカー: ラムダノート
  • 発売日: 2017/10/23
  • メディア: 単行本(ソフトカバー)

IntelliJ Plugin 「kotlin-fill-class」の現在

この記事は suusan2go Advent Calendar 2019 - Adventar の12日目の記事です。

kotlin-fill-classとは

自分が趣味で作っていたIntelliJ IDEAのPluginで、Kotlinのコンストラクタを(実は今は関数の引数も)シュッと補完してくれます。

suzan2go.hatenablog.com

実際に見ていただくとどんなものか分かるかと思います

https://user-images.githubusercontent.com/8841470/59397528-e61a4380-8dc7-11e9-9684-d82d225316fe.gif

Kotlin Festのなかでも発表させていただきました。

公開されたあとも地味に色々と機能が追加されているので、このブログではその紹介をします。

kotlin-fill-classの現在

独自クラスでも再帰的にコンストラクタを埋められるようになりました

これまではInt, Stringなど組み込みの型については自動で埋められていたものの、 例えば以下のようなValue Objectを用いたユーザー定義クラスの型は値を埋めることができませんでした。

data class UserName(val value: String)

data class UserId(val value: Int)

data class User(
        val id: UserId,
        val name: UserName
)

user = User(id: , name: ) // fill constructorしても値は空欄になってしまっていた。

それが、現在は以下のように再帰的に独自クラスのコンストラクタも呼んで値を埋められるようになりました。

non empty

以下のプルリクで対応されました。

github.com

関数の引数も値を埋められるようになりました

kotlin-fill-class という名前の通り、もともとはコンストラクタをターゲットにしていましたが、なんと現在は関数にも対応しています。

function

以下のプルリクで対応しています。

github.com

もはや kotlin-fill-class という名前でいいのかという感じになってきましたが、なんかいい名前ください。

import分も自動で追加されるようになりました

これはコンストラクタにユーザー定義のクラスを含んでいた場合に、自動でimportされるようになりました。 github.com

テストが追加されました

ユーザーからすると関係ありませんが、テストが追加されました。以下のプルリクでCircleCI回していますが、テスト書いてくれたのは @t-kameyama さんです。

github.com

その他

補完されても嬉しくない箇所で補完されていた箇所など、ちょっと使いにくかったところが改善されています。

github.com

github.com

謝辞

プルリク見ていただくと分かりますがこの辺の大きな機能追加や細かな改善は自分ではなく、@t-kameyama さんという方がやってくれています。もはや自分のコードは殆ど残ってなくて、自分がやってるのはIdeaのバージョンがあがったときに動作確認してプラグインの依存を上げるのと、チェンジログを書いてJetBrainsに公開するくらいです。@t-kameyama さん、PR頂いたときにお礼を言うくらいしか出来てませんが本当にありがとうございます!!!!!

@t-kameyama さん以外にも、 IntelliJがアップデートされたタイミングで「サポートしてくれーーー」ってIssueを上げてくれる人や、プルリクを上げてくれる人がいて嬉しい限りです。顔も名前も知らない、なんなら国も違う人が自分の作ったものをガンガン改良していってくれてるの、凄い。普段利用者としては正直あまり意識していないけど、OSSってすげーなとPRやIssueもらうたびに思います。

残念ながら最近は仕事でKotlin書いていないので機能面での改良はなかなか思いつきませんが、今後もほそぼそとメンテナンスしていきます。今後ともkotlin-fill-classをよろしくお願いいたします。

ソフトウェアファーストを読んだ

この記事は suusan2go Advent Calendar 2019 - Adventar の11日目の記事です。

古巣のインタビューが乗ってることもあり、ソフトウェアファーストを読んだ。

ソフトウェア・ファースト あらゆるビジネスを一変させる最強戦略

ソフトウェア・ファースト あらゆるビジネスを一変させる最強戦略

感想

一般的なWEB企業で働いた経験のあるものからすると、そこまで真新しいものは無いかもしれない。自分がSIerにいたときにこんな本が読めたらもっとがんばれたかもなーと思った。この本の主題とはちょっと外れることかもしれないけど、自分はエンジニアの組織やキャリアに関する話で結構考えさせらた。

ソフトウェアエンジニアのキャリア

ぽつぽつとTwitterにも呟いたのだけれど、主にこのあたりの話

本から引用するとこの辺りとか

同期の2人が同じ時期にスタートを切って、Aさんはエンジニア(スペシャリスト)の道を選び、Bさんは途中からマネジャーに転向したとしましょう。マネジャーは担当する組織の大きさに比例して貢献度を図れるので、Bさんは組織規模が大きくなるのに合わせて収入も増えていきます。一方、エンジニアのAさんはどうなったでしょう?自分もマネジャーのBさんと同じくらい評価されたいですし、年収もほしいと思っています。100人の部下がいるマネジャーのBさんと同じくらい評価されるにはどうすればいいでしょう 及川 卓也. ソフトウェア・ファースト (Japanese Edition) (Kindle の位置No.4013-4018). Kindle 版.

この辺りとか

エンジニアの純粋な(狭義の)技術力が右肩上がりで成長し続けることはまれで、どこかのタイミングで鈍化するのが普通です。ここで言う純粋な技術力とは、コーディングスピードであったり、コードの品質であったりします。もちろん技術の幅を広げるという方向性もありますが、いずれもどこかで一次関数的な成長は難しくなり、技術的な成長が高止まりしたままだと評価も停滞を余儀なくされます。 及川 卓也. ソフトウェア・ファースト (Japanese Edition) (Kindle の位置No.4018-4021). Kindle 版.

これは、「だからこそスペシャリストとなる人間が何をもってエンジニアリングマネージャーやプロダクトマネージャーと同等とみなせるのか定義しておく必要がある」という文脈での話ではあるんだけど、「自分はいまT字型の- の部分をめっちゃ広げている感じになってしまっている」と自覚しているので、余計に来るものがあった。

何かを深く掘っていくか、はたまたエンジニアリングマネージャーやプロダクトマネージャーといったところに行くのか、まだ何も決めていないけどこの本を読んでから次の方向性を探しにいっている。

VSCodeからWebStormに乗り換えた

この記事は suusan2go Advent Calendar 2019 - Adventar の10日目の記事です。

最近のサーバーサイドの開発ではほぼJetBrainsのIDE (RubyならRubyMine、GoならGoLand、PythonならPyCharm、サーバーサイドじゃないけどFlutterならAndroid Studio)を使うようになったものの、フロントエンドだけは別でVueやTypeScriptのサポートの厚さからVSCodeを使い続けていました。しかし、一つだけショートカットの違うエディタを使うと結構生産性が落ちるのと、リファクタリングの機能はJetBrains製IDEの方にかなり軍配があがるので、関わっているプロジェクトのコードのリファクタリングを考えるタイミングで乗り換えることにした話です。

WebStormに乗り換えるにあたっての設定

自分はフロントエンドだけかけばいいときはWebStormを立ち上げてますが、PHPStormでもRubyMineでもJS書く環境は同じようにサポートされています。このセクションのタイトルも便宜上WebStormになってますが、以下の設定などはWebStormじゃなくてもほぼ同じです。

ESLint設定

ESLintはIDEに組み込みで入っています。プロジェクトにESLintが設定されていれば特になにもしなくてもいい感じに設定されるはずです。 f:id:suzan2go:20191211121218p:plain

Prettier設定

Prettierはプラグインとして提供されています(WebStormならデフォルトで組み込み)。ただこのプラグイン単体では、 Format on Save は提供されていないのでFileWatchersと組み合わせることになります。 f:id:suzan2go:20191211121814p:plain

FileWatchersもプラグインとして提供されており(WebStormならデフォルトで組み込み)、これとPrettierのプラグインを組み合わせることで Format on Save が実現できます。こうかくと結構面倒そうに感じるんですけど、実際にはFileWatchersの追加からprettierを選んで対象のテンプレートを選択するだけなので楽ちんです。

f:id:suzan2go:20191211122701p:plain

f:id:suzan2go:20191211122612p:plain

注意としてデフォルトではScopeが Project Fiels になっていますが、Recently Changed FilesCurrent File にしておくと良いでしょう(ビルドしたJSとかを全部フォーマットにしにいって重くなることがある)。

Vueサポート

これが一番心配だったんですけどちゃんとVueプラグインが提供されています。最初にpublishされたの Feb 03, 2017 だから結構前からあったのか知らなかった……

plugins.jetbrains.com

VSCode向けのプラグインであるVeturがかなり高機能だったので心配してましたが、ほとんどストレスなく開発ができています。 github.com

乗り換えてみての感想

直近Vueを書くときにつかっていたので、Vueでの感想が中心です。

補完とジャンプが強い

VSCodeでもコード補完とジャンプは出来てましたが、WebStormの場合のほうがやはり強力で型で引けない場合にも候補を出してくれるのはかなり強いです。VSCodeと比べても、Vueのシングルファイルコンポーネント <template> 内の補完が快適で驚きました。

VSCodeの場合、data() 内の最初のキーまでしか補完してくれなかったんですけど(自分の環境だけ?)、オブジェクトの中身についてもちゃんと補完を出してくれています。

f:id:suzan2go:20191211125212p:plain

またコンポーネントのpropsについてもちゃんと補完が効いています(これはVSCodeも同じ)。

f:id:suzan2go:20191211125703p:plain

リファクタリングがやりやすい

リファクタリングがめちゃめちゃやりやすくなりました。Vueのコンポーネントファイルの中にベタで書いていた関数を外部ファイルに移す、1ファイルにまとめて書きすぎた関数を別ファイル分割するみたいなことが簡単に実現できるので、ファイルの整理が捗るようになりました。もちろんちゃんとそれらを呼び出していたファイルでもimportパスの変更などは自動で追随してくれます。

f:id:suzan2go:20191211130205p:plain

computed の関数名をリファクタリング機能で変更するとテンプレート内にもちゃんと反映されますし*1VSCodeで触っていたときよりもリファクタリングの面倒さが格段に少なくなりました。

複数のショートカットキーを覚えなくてよくなった

これはめちゃくちゃ個人にしか当てはまらない感想ですが、VSCodeとJetBrains系IDEを行き来していたときによく脳内でショートカットキーがコンフリクト起こしていたのがなくなったのは地味に大きかったです。特に直近はVSCodeを触る機会がフロントエンド触るときだけに限定されたこともあって、久しぶりにVSCode側を触るときに基本的なショートカットキーが思い出せなくてググったりしていたので……

良くなかった点

いいところばっかりだとステマっぽいので微妙なところも書いておくと、やはり立ち上がりがVSCodeに比べると遅いです。ちょっと何かを編集するみたいな用途に立ち上げるのは向いてないです。自分は今までもそういうちょっとした変更ではVimを使っていたので特に困ってないですが。 あとは最新のAPIに対応していない場合もあるようで、Vue内の v-slot:hogehogeシンタックスハイライトがうまくいっていませんでした。また自分は試してませんが、レビュー を見ると、Vue Composition APIにまだ対応してないようです。 https://plugins.jetbrains.com/plugin/9442-vue-js/reviews#review=35618

まとめ

これでアプリケーションコードを書くものは全てJetBrains製品となりました。フロントエンド書くならVSCodeでしょ!と特に試しもせずに思っていましたが、有償のIDEだけあってJetBrains製品もなかなか良いです。

*1:残念ながら完璧ではないですが……

個人のメモとしてNotionを使いはじめた

この記事は suusan2go Advent Calendar 2019 - Adventar の9日目の記事です。

個人のメモとしてNotionを使い始めました。

これまで

個人が無料で使えるkibelaを使ったり、Boostnoteを使っていたりしました。Notionは仕事で使ったことがあったものの、以下の点が微妙だなーというのが正直な感想でした。

  • ピュアなマークダウンではかけない
    • 例えば ####Heading として評価されないとか
  • 検索が弱い
    • 使っていたのは半年以上前の話なので分からないけど、日本語での検索が弱い印象でした
  • カンバン・リストも結局は専用のツールのほうが使いやすい
    • オールインワンであることはメリットなのだけど、正直開発のタスク管理としてはJiraやZenHubのほうが使いやすかったです
  • Slack通知が弱い
    • 下書きみたいな概念がないので、書いてる途中でガンガンSlackに通知が飛んでいき、結果として通知が意味をなさないみたいな状況がありました
  • 記事のタイムスタンプがファーストビューでは見れないので何が新しい記事かが分からないし、Slack通知の件もあって情報にキャッチアップしていくのが難しい
  • 本文中で :emoji: が使えない。そんなに多用するわけじゃないんだけど、ないと寂しい…

※今はよくなってるよ!とかあれば教えてください。

いきなりディスってしまったけど、個人用として使いだしたら結構いいなーと思えたので、その話をします。

個人で使いはじめて感じたNotionのいいところ

Web Clipperがある

Web Clipper の機能が提供されたのが大きくて、個人として使い始めたのはこれが理由でした。パブリックなページなら、中身のテキストも取ってきて編集できるのがいい感じです。

f:id:suzan2go:20191209155612p:plain

調べ物してるときに、いくつかページをぐるぐるして「あーあのページに書いてあったこと試してみればよいのでは?」と閃いたあと、肝心のページになかなかたどり着けないみたいなことありませんか。自分はよくあります。とりあえずWeb Clipperで取得してコピーしておけば、あとはNotion上で完結できるので、重宝しています。

下書き・公開という概念がない

これはチームで使っていたときにはむしろよくない点でもあったのだけど、個人として使う分にはむしろしっくり来ました。基本的に「あー書いたのに消えてしまったーーー」ということが無いし、保存みたいな概念がなく勝手に保存されていくので普通にメモみたいな感じで使えています。

カンバン・カレンダーを一つのページに埋め込める

これもチームで開発する上ではやはり専門のツールが欲しいなと思ってしまったところだけど、個人でちょっとタスク管理したいくらいの用途だと組み込みのカンバンやカレンダーで十分高機能で、これも重宝しています。自分のダッシュボードみたいなものを作って、勉強しておきたいことなどをまとめておいたり、稼働のスケジュールを考えたりなどしています。

個人で使いはじめて感じたこと

調べたわけじゃないので完全に想像なんですけど、Notionって最初は個人向けに作られていたのではという気がするんですよね。そう考えるとチームで使ったときに自分が感じた使いにくさみたいなものの説明ができる気がする。まだチームで使うツールとして自分がNotionを選ぶかというと選ばないけど、個人で使うツールとしては結構手に馴染むので、どこかのタイミングで「チームのWikiとしてNotionいいぞ!!!」となるのかもしれない。

改めて ロードマップ を見ると、API や BetterSearch、TimlineView なんかも Coming Up とのことなので、この辺が来たらチームとしても使いやすいツールになりそうだなーと期待しています。

Cloud Dataflow で Cloud SQLからBigQueryにサーバーレスにデータ連携する その2

この記事は suusan2go Advent Calendar 2019 - Adventar の8日目の記事です。

その1はこちら

suzan2go.hatenablog.com

上記の記事では以下のようなJSONを用意してCloud SQLからBigQueryにデータ連携する仕組みを作ったのだけど、テーブル追加の度にこのJSONを書くのが面倒になって、指定したテーブルだけをガッと全部とってこれないかなと思って作り直した。

- query: "select * from users"
  output_table_name: users
  fields:
    - name: id
      type: INT64
      mode: REQUIRED
    - name: avatar_url
      type: STRING
      mode: REQUIRED
    - name: nick_name
      type: STRING
      mode: REQUIRED

普段全くJava書いてないので、結構変なコードがあるかもしれない・・・というエクスキューズをしておきます :pray:

BQのスキーマ指定なしでもDBからスキーマを自動生成してデータを同期したい

もともとの記事でYAMLを用意していた理由は以下の2つ。

  • 同期したい・したくないカラムを柔軟にカスタマイズできるように
  • 参考にしたSQL to BQのテンプレートがBQのスキーマ情報を要求していた

前者についての要望はもちろんあるものの(emailをコピーしたくないとか)、どちらかというと後者の実装面での制約が大きかったので、ガッと作ることにした。 調べてみると、BigQueryIOは withSchemaFromView というAPIを持っていて、DataflowのPipelineの中で計算したschema情報を指定できるようなので、それを使うことにした。

コードでいうと以下のような変更になる

BigQueryIO.writeTableRows()
        .withoutValidation()
        .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED) // テーブルがなければ作成する
        .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_TRUNCATE) // 既存のテーブルを消して書き込む
-       .withSchema(schema.getTableSchema())
+       .withSchemaFromView(schema)
        .ignoreUnknownValues()
        .withCustomGcsTempLocation(options.getBigQueryLoadingTemporaryDirectory())
        .to(new CustomTableValueProvider(schema.getOutputTableName(), options.getOutputDataset())));

PostgreSQLのInformation Schemaの利用

方針としてはPostgreSQLを見に行って、テーブルのカラム情報と型情報を取得し、それをもとにBQのスキーマを組み立てていけばよい。

基本的にテーブルのカラムの情報は information.schema.columns を見に行けばよい。 table_name で絞り込み data_typecolumn_nameis_nullable といったカラムの情報をもとにテーブル情報を取得できる。注意しなければいけないのはArray型で、以下のドキュメントにも書いてあるがこのテーブル Array までしか分からず Array<int> なのかどうなのかを知るには elemenmt_types まで見に行く必要がある。

35.16. columns

実際に発行するクエリとしては以下のような形になる。

 String schemaQueryTemplate = "SELECT c.column_name as COLUMN_NAME, c.is_nullable AS IS_NULLABLE, c.data_type as DATA_TYPE_NAME, e.data_type AS ELEMENT_TYPE_NAME,\n" +
         "    pg_catalog.col_description(format('%%s.%%s',c.table_schema,c.table_name)::regclass::oid,c.ordinal_position) AS COLUMN_DESCRIPTION\n" +
         "FROM information_schema.columns c LEFT JOIN information_schema.element_types e\n" +
         "     ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier)\n" +
         "       = (e.object_catalog, e.object_schema, e.object_name, e.object_type, e.collection_type_identifier))" +
         "where table_name = '%s'";

このクエリ結果をもとに、地道にBQのスキーマを組み立てればよい。

Pipelineで上記のクエリ結果からBQのスキーマ情報を組み立てる

JdbcIOというクラスを使って、上記のクエリ結果を一行一行処理していき、最後にまとめていけば良い。

結果をBigQueryのスキーマ情報に変更する

これはかなり力技なのだけど、DBのTypeをもとにBQのTypeに変換していく。上述したようにArrayだけはelement_typesの型を見に行かないと実際の型が分からないことに注意が必要。

    // 変換用のMap ※一部抜粋
    private static final Map<String, String> postgresqlToBqTypeMap = ImmutableMap.<String, String>builder()
            .put("integer", "INT64")
            .put("character varying", "STRING")
            .put("date", "DATE")
            .build();


.withRowMapper((JdbcIO.RowMapper<Map<String, String>>) resultSet -> {
    String columnName = resultSet.getString("COLUMN_NAME");
    String typeName = resultSet.getString("DATA_TYPE_NAME");
    String elementTypeName = resultSet.getString("ELEMENT_TYPE_NAME");
    String description = resultSet.getString("COLUMN_DESCRIPTION");
    String isNullableString = resultSet.getString("IS_NULLABLE");

    String mode;
    String type;
    if(typeName.equals("ARRAY")) {
        type = postgresqlToBqTypeMap.get(elementTypeName);
        mode = "REPEATED";
    } else {
        type = postgresqlToBqTypeMap.get(typeName);
        mode = isNullableString.equals("YES") ? "NULLABLE" : "REQUIRED";
    }

    if(type == null) {
        throw new IllegalArgumentException(
                "can't detect bigquery schema type from postgres type: " + typeName + " elementType: " + elementTypeName
        );
    }

    Map<String, String> map = new HashMap<String, String>();

    map.put("mode", mode);
    map.put("type", type);
    map.put("name", columnName);
    map.put("description", description != null ? description : "");
    return map;
})

データを結合して一つのスキーマにする

上記の状態から最終的なアウトプットとして { [table名]: <BQ schema json>} な形式に変換して上げる必要がある。ここで使うのが Combine というもの。

beam.apache.org

このCombineの概念をちゃんと理解せずに、 「reduce みたいなもんでしょ」とか舐めてたらめちゃくちゃハマってしまった。サンプルとして以下のようなコードが書かれていたので余計に勘違いしてしまったのだけれど、もうちょっとやっていることは複雑。

public static class SumInts implements SerializableFunction<Iterable<Integer>, Integer> {
  @Override
  public Integer apply(Iterable<Integer> input) {
    int sum = 0;
    for (int item : input) {
      sum += item;
    }
    return sum;
  }
}

公式ドキュメントにも書いてあるとおり、実際の処理の流れとしては以下のようになっている。

  • Create Accumulator creates
    • 集計用のデータをローカルに作成
  • Add Input
    • それぞれの集計用のデータにinputを追加
  • Merge Accumulators
    • 集計用のデータを一つにまとめていく ※この処理は複数回呼ばれる
  • Extract Output
    • アウトプットのデータ構造を作成

Merge Accumulatorsは複数回呼ばれるのでそれを想定した作りにしておく必要があって、それを理解してなくてかなり時間を食ってしまった。実装でいうと上記の処理に対応した関数をもつクラスを作ってやればよく、素朴に実装すると以下のようになる。

    public static class SchemaInfoToBigQuerySchemaFn extends Combine.CombineFn<Map<String, String>, List<Map<String, String>>, Map<String, String>> {
        public CustomTableValueProvider  tableValueProvider;
        private final Logger LOG = LoggerFactory.getLogger(SchemaInfoToBigQuerySchemaFn.class);

        SchemaInfoToBigQuerySchemaFn(CustomTableValueProvider value) {
            this.tableValueProvider = value;
        }

        @Override
        public List<Map<String, String>> createAccumulator() { return new ArrayList<Map<String, String>>(); }

        @Override
        public List<Map<String, String>> addInput(List<Map<String, String>> accum, Map<String, String> item) {
            accum.add(item);
            return accum;
        }

        @Override
        public List<Map<String, String>> mergeAccumulators(Iterable<List<Map<String, String>>> accums) {
            List<Map<String, String>> merged = createAccumulator();
            for (List<Map<String, String>> accum : accums) {
                merged.addAll(accum);
            }
            return merged;
        }

        @Override
        public Map<String, String> extractOutput(List<Map<String, String>> accum) {
            TableSchema tableSchema = new TableSchema();

            List<TableFieldSchema> fieldSchemaList = new ArrayList();
            for (Map<String, String> item : accum) {
                fieldSchemaList.add(
                        new TableFieldSchema()
                                .setName(item.get("name"))
                                .setType(item.get("type"))
                                .setMode(item.get("mode"))
                                .setDescription(item.get("description"))
                );
            }
            tableSchema.setFields(fieldSchemaList);
            String destinationValue =  tableValueProvider.get();
            TableDestination destination = new TableDestination(destinationValue, "");

            Map<String, String> schemaMapValue = Maps.newHashMap();

            String json = new Gson().toJson(tableSchema);
            schemaMapValue.put(destination.getTableSpec(), json);

            return schemaMapValue;
        }
    }

まとめ

  • PostgreSQLからデータを抜いて、実行時に動的にBQのスキーマを取得することができた
  • 頑張ったしApache Beamの勉強にもなったけど、運用的には最初のJSONを自動生成してカスタマイズできるほうが嬉しかったかもなぁーと今は思っている・・・・・・

大企業に残った友人と話して分かった大企業の今

この記事は suusan2go Advent Calendar 2019 - Adventar の7日目の記事です。

少し前に、自分が新卒で入った会社の同期の友人から転職相談を受けて、自分がいたときとは会社の状況とか従業員としての状況とか色々結構変わったんだなと思ったので書いておく。

大きくわけると2つ変わったことがあった。

  • 時代の流れもあって会社自体が当時から変わったこと
  • 30代になって当時から変わっていること

自分は新卒で入った会社に3年くらいいて20代後半でベンチャーに行ったんだけれども、正直一時期は「大企業よりもベンチャーの方が潰しの効く経験詰めるしいい」「給与もエンジニアなら悪くない」「働きやすさもベンチャー企業の方が上」みたいなことを思っていた。しかし友人と話してみると、自分の持っていたイメージは大分古いのかもなと感じた。

大企業ってどこよ

所謂大手のSIer、メーカーで従業員が十数万人といった規模の会社。自分のプロフィールとか見に行くと普通に書いてあるので気になる人は探しにいってください。また大企業のなかでのある部署の話なので、あまり一般化はできないと思う。なのでタイトルはちょっと釣り気味です。またこのブログの公開については友人から許可を得ています。

大企業での働きやすさ

少なくとも自分がいた当時は働きやすいとは全くいえない環境で、8:00に出社して11:00に会社をでるみたいな生活が普通だった。フレックスなんて制度もなくリモートワークなんてありえなかった。しかし話を聞いてみると以下のような状況らしい。

  • フレックス(コアタイム無しのフルフレックスも業務上必要であれば認められている)
  • リモートワークも朝にメールを一通出せばOK

所謂WEB系のベンチャーでもリモートワークとフルフレックスを認めている会社は実はそれほど多くないと思うので驚いた。また残業についても、「赤字を出しても案件を取る / 死ぬほど残業して働く」みたいな働き方は割と認められなくなってきているらしい。(ただこれは部署によるところも大きい気がする。未だに月80時間残業くらい普通にやってる人間を知っているので)

ただパソコンにキーロガーみたいなのが仕込まれてて、パソコンを開いているか、どの画面を開いているかは常に記録されて勤怠システム上で閲覧可能になっているらしく、そういうところはアレだなと思った…

大企業での給与

自分が最初に会社をやめて転職したときには結構給与を下げた。それでも3年後くらいには最初の会社時代の給与を大きく超える額になったし、フリーランスになった今は金銭的にはかなり楽になっている。自分が給与を下げても最初の転職に踏み切れたのは、「このまま残っても給与が上がるイメージが持てなかった」というのもあるのだけど *1、友人と話していると30歳を超えてくると大企業もグッと給与が上がってくる事がわかった。会社として若手を早くマネージャーに上げようという流れもあるらしく、来年や再来年にマネージャーに昇進すると一気に800〜1000万くらいの年収にはなるらしい。

また、会社の中にいた一日中仕事と関係ない本を読んでるか昼寝してるだけの人、仕事は全然できないけどXXXエキスパートなる肩書を持っている人、そういう方々も700万から800万くらい年収をもらっていたということが分かってきて、大企業の懐の広さすげえなと思った。

大企業でのキャリア

今回話した友人は、国レベルの仕事や、世界中の拠点と関わる仕事をやっているらしく、そういうスケールの大きさはやはり大企業でしかできないことだろうなと思った、一方で本人も言っていたのだけど、「自分が何の仕事をしているか」「どんな成果を出したか」を個人レベルで語るのが結構難しい。エンジニア、デザイナーであれば、「こんなサービスを作りました」「こんなシステムを作りました」のように言えるし、SEでも「大企業XXXXプロジェクトのPMやりました」みたいなことは言いやすい。が、大企業の中だと何ていうか外部に一般化できない仕事をしている部署というのがチョイチョイあって、そういう部署に行くと職務経歴の説明が難しい。その友人も部署ではかなり評価されているようなのだけれど、「このままこの部署でマネージャーになって、つぶしの効く経験ができるのだろうか」ということに悩んでいるようだった。

ただ、自分はもともと大企業の中に残ってそこでしか通用しないスキルを磨くことに危機感があったのだけど、今は「エンジニアとしてコードを書いてアプリケーション / サービスが作れる」というだけのスキルはどんどんコモディティ化しているなと感じるし、正直なところWEBエンジニアとして次に何をしていくべきかということに結構悩んでもいる。なのでこういったキャリアの悩みは、単純に大企業だから / スタートアップ・ベンチャーだから、という話でもないのかもしれないなと今は感じている。

まとめ

正直にいうと、30歳になるまでは大企業で悩んでいる友人らには「スタートアップ / ベンチャーいいよ!」という勧め方をしていたのだけど、30歳超えて大企業のなかでも評価されている人らには中々そういう安易な勧め方はできなくなってきたなと感じる。本人がやりたいかどうかとは別にしても、大きな企業じゃないと出来ないことというのは確実にある。要は大企業、スタートアップ / ベンチャーにいることのどちらにもリスクがありメリットもデメリットもあるので、当たり前の話だけど一つの物差しで簡単に測れるものではないなと思う。

次に行く会社の選択肢としては基本的にWEBベンチャーしか考えていなかったのだけど、普通のWEB企業と比べても遜色ない環境でエンジニアとして働ける大企業もボツボツと出てきている印象があって、大企業の中で内製化された(しようとしている)部署があるなら、そういうところでも面白いかもなぁーと漠然と最近は考えている。

*1:もちろん一番の理由は自分でコードを書きたかったからだったけど