転職活動〜退職までにやったこと(注: 3年前)

はじめに

このエントリでは、転職や退職の理由などについては、その一切を扱いません。

また、現職や転職先について、類推できうる情報は削除していますので、その点はご承知いただけますと幸いです。

あくまで転職にあたって、自分の動きを整理するエントリになりますので、転職活動をお考えの方について参考になれば程度の内容になります。

右に書いてある期間については、退職日・入社日に対応しています。(まだ更新中です。)

転職先の内定まで(~3ヶ月前)

振り返り(~3ヶ月前)

これは一般に自己分析と呼ばれるものだと思われるが、我流でやったため正当な方法であるかはわからない。

新卒の就職活動時も、一般的な対策などを本で確認したり実施したわけではないので、下記のことが役立つかは分からない。

やったことは下記のことを5回程度繰り返したものになる。 - 一般的に転職をするにあたって、転職の理由、現職やそれ以前の活動、自分に関する意見(長所、短所など)を聞かれることが一般的であるらしい。 - 脳内に仮想的に質問してくる人間を用意し、全てについて「なぜ」を質問するように仮定し、返答を考える。 - 自分の返答を紙に書き出してメモする。

自分の場合は、このステップを通して、次の職について、ざっくりどの会社に行きたいかというのが見えてきた。

職場に関する下調べ (~3ヶ月前)

振り返りの結果得られた、行きたい先の会社について下調べをする。

もし知人に在籍している方がいたら、業務内容や雰囲気について聞いてみたりして、自分の目的とのギャップなどについて確認をする。

同じ職場でも職種によって大きく違うケースもあるので、紹介などを通して可能であれば同じ職種についている人に、話を聞いてみるのがベターだと感じた。

リファラル採用に力を入れている会社は多いので、リファラル採用などを実施していないかを確認する。

応募(~3ヶ月前)

履歴書を書き上げる。

転職先について類推できうる情報を伏せたいため、詳細はここでは扱わないものの、日系企業であれば和文履歴書(バイトとかに持ってくやつ)と職務経歴書外資であればResume/C.V.を書くことが一般的だろうか。

選考(~3ヶ月前)

ここについては選考の期間、期間を含めてあまり言及できることがない。

ただ前述の振り返りをちゃんとやってると、確実に楽になると思う場面は存在したので、やっておくといいかもしれない。

内定~退職・入社まで(1ヶ月前)

内定承諾

大体、入社の1ヶ月前に内定承諾書が送られてくるケースが多い。

自分の場合はたくさん受けてはいなかったので、オファーのどれかで迷うことはなく承諾。

退職の申し出と手続き

これが本エントリ最大の山場。確認することが山のようにある。特に後半の神仕事は大変。

退職の申し出

上司に退職したい旨を伝える。退職日は一応候補日を用意しておいて伝える。

"相談"とすると引き止められることがあるらしいと聞いたので、"お伝えしたいこと"という表現を選ぶといいとググったら書いてあった。

会社や上司によっては、ここで苦労する人も多いと聞くので、話に耳を傾けていただいただけでとてもありがたかった。

比較的図太く見える自分でも、当日よく寝れずガチガチに緊張していたので、 報告の後は緊張感が解けて、つい部屋着のまま家の外をうろうろしてしまい、公園で職務質問を受けることになった。

引き継ぎ

自分の担当業務のリストを作って、業務知識の書き出しと引き継ぎに必要な手続きや作業などに整理をする。

数年の単位で在職すると、主となる担当業務の他に、その合間などにやった作業が掘り出されてきて、そちらの整理が大変だった。

この作業を通して、普段から自分が実施した作業は、細かい部分も含めてちゃんと列挙しておくことが、重要であると分かった。

会社を辞めることはそんなに頻繁にないけれど、成果報告書に書いていない内容を発見したこともあったので、しっかり作業記録を残すことは価値があると思った。

退社のための手続き

上長と話した後、人事とのやりとりをする。

退職の理由などについては、必要最小限な範囲ではあるが丁寧に答えた。これも振り返りの部分が大きく役立ったと思う。

去るにあたっての文章などの準備は、しっかりしたほうがいいと思った。

入社のための手続き
  • 給与関連書類
  • 学歴証明書
  • 住民票
  • 身分証明証 などなどを用意した。

特に自分の出身大学は、証明書以外にサービス利用料を請求してくるため、安くしてほしいと思った。(慶應義塾の大学関係者はなんとかしてください)

会社によっては会社宛の電話での身辺調査(在籍確認など)があるので、入社の意思を伝えたら速やかに、会社(上司)に伝えておいたほうがいいと思った。

おわりに

転職は言わずもがな大きな決断だったのもそうですが、退職すると決めたら少し楽になるかと思っていたら、引継ぎから退社までが思ったより大変だったので、少なくとも自分には頻繁にできることではないなと思いました。

リーダブルコード読書メモ

数年ぶりにリーダブルコードを読んだので自分用メモ。メモの内容は目次に対応。

表面上の改善

理解しやすいコード

  • わかりやすいコードは理解にかかる時間を指標にするのが良い

名前に情報を詰め込む

  • 多義的な語を避ける
  • 何を指しているかわからない語を避ける
    • size => height, bytes
  • tmp, retvalなどは最小限にする
  • ループイテレータも添字を工夫することができる
    • n重ループを書くときに、添字の対象を書く
      • foo_i, var_iみたいな形式
  • 一つの機能が複数のことを意味してないか考える
    • 実はそれぞれ独立した別の機能では?
  • 扱っているデータの形式・特性を変数の先頭・末尾に持ってくる
    • 16進数の場合: hex_foo
    • ミリ秒の場合: foo_msec
    • 平文: plaintext_foo
    • UTF: foo_utf
  • ハンガリアン記法(接頭辞):
    • p: pointer, S: string, c: count, ch: char, m: map
  • スコープが大きくないなら説明的な名前でなくても問題ない
  • 無くても成り立つ場合は極力シンプルに記述する
    • ConvertToString => ToString
  • フォーマットに工夫をする
    • クラス名: キャメルケース, 変数: ローワーケース, マクロ: 大文字のみ
    • アンダースコアでローカル変数であることを表現する
    • その他(JS)
      • コンストラクタ関数は大文字でスタート
      • $で始まる変数はjQuery

誤解されない名前

  • filter => filter_outなのか、filter_inなのかわからない
  • 限界値をふくめる場合 => max, min
  • 範囲を指定する場合 => first, last
  • 範囲の包含・排他の場合 => begin, end
  • 名前を否定系にしない
  • 実行する処理の計算量を意識させる書き方をする
  • 誤解される余地を検討しつつ名前を決める

美しさ

  • 一貫性のあるレイアウトを使う
    • 改行の箇所がズレて目立ってしまうものを避ける
    • カッコのスタイルを合わせる
  • 似ているコードは似ているように見せる
  • 関連するコードはブロックにする
  • 隠蔽用のメソッドを用意することでシンプルにすることができる
  • 行の縦方向を合わせることで、何をAssertしているかわかりやすくすることができる
  • 意味のある順番に並べる
    • アルファベット順
    • 重要度順
    • 実装されている他のものに合わせる
  • メソッド定義を種類によって分けて並べてあげたりする
  • コードを段落に分解する
    • まとまった処理で区切る

コメントすべきことを知る

  • コード単体から読み取れることを書かない
    • ただし読み取るのに時間がかかるケースは有効
  • コード自体を変えるほうが良いケースがある
    • 変数名・メソッド名が分かりにくいなど
  • 試した結果や工夫・今改善すべき事項などはコメントとして残す
    • TODO, FIXME, HACK, XXX
  • 期待される値(max_threads)などを記録しておく
  • ざっくりとした全体像(クラス設計など)の説明を書く

コメントは正確で完結で

  • 短く書く
  • 代名詞を避ける
  • 具体的に書く
    • ~に応じて~を変える=>~に応じて~を増減させるなど
  • 入出力のコーナーケースを書く
  • コードのロジックの意図を書く
  • 引数付きコメントを上手に使う

ループとロジックの単純化

制御フローを読みやすくする

  • 式を書くときは自然言語をなぞると良い
    • もし君が18歳以上ならば: ○
    • 18が君の年齢より大きければ:×
  • 条件は否定形よりも肯定形にする
  • 単純な条件もしくは目立つ条件を先に書く
  • 三行演算子は理解しやすい範囲に留める
  • do-while => while
    • 終了条件が後置的だと読みにくい
  • returnはコード中で返しても構わない
    • 返り値の整形はエラー処理の一部として書ける
    • returnを使うことでelse文が削減できることがある
  • gotoは処理の流れが読みにくくなるので避ける
  • continueを上手に使うとloopのelse処理が減らせることがある
  • 機能を追加した時は追加後の全体像を一度見る
  • スレッド、割り込みハンドラ、例外処理、関数ポインタ、無名関数
    • 処理全体の流れが見えなくなることがある

巨大な式を分割する

  • 説明変数・要約変数を使う
    • 文字列処理などをそのまま使わず、意味のわかる変数に代入する
    • 式の結果などを別に処理して代入しておくことで、分かりやすくなる
  • ド・モルガンの法則
    •  not (A or B or C) => not A and not B and not C
    •  not (A and B and C) => not A or not B or not C
    •  notを分配してorとandを反転させる
      •  notをくくりだして、orとandを反転させる
  • 短絡評価を上手に使う
    • &&の前半の評価の結果で後半が読まれないように書くことができる
    • 式に||を使うと先頭から評価されていき、真と評価された値が代入される
  • マクロを上手に使うと代入をスムーズにすることができる
    • 類似している変数の同時代入など

変数と読みやすさ

  • 変数は必要がある程度に説明的でない限り削減する
  • 中間結果の保持も最小限に留める
  • 条件分岐を管理するための変数は可能な限り削除する
  • グローバル変数・メンバ変数は最小限に留める
    • 可能な限りローカル変数を使う
    • クラスそのものを小さく保つ
  • if文の中だけでしか使わないのであれば、代入式をそのまま評価することもできる
  • Closure, varを使う(JS)
  • ブロックスコープを上手に使う
  • 変数定義は変数が必要なタイミングで実施すれば良い
  • 変数の再代入は最小限に留めると挙動が読みやすくなる

コードの再構成

無関係の下位問題を抽出する

  • 直接無関係なロジックは外に切り出す
    • 幾何計算と最短距離の選択は独立したロジック
    • ファイルの読み書きを隠蔽する
    • JSONや文字列を整形する機能
  • イケてない標準ライブラリはwrapper関数を書くと良い
  • やりすぎると追わなきゃいけない全体の流れが多くなる

一度に一つのことを

  • パースと実際の処理は別々に記述することができる
  • 値がなかったら置き換える=>デフォルト値を設定して見つかったら上書きする
  • 複数のロジックがある場合分割することを考える

コードに思いを込める

  • 人間の考え方に沿った書き方をすると理解がしやすくなる
    • 思考の流れに近い記述がなされていると、プログラミング言語的には読みにくいものでも、読みやすくなることがある
  • 手順を書き出して本質的なロジックを見つけて実装し直していく

短いコードを書く

  • 汎用ロジックを切り出す
  • 未使用コードを削除する
  • 標準ライブラリの関数・モジュール・型にちゃんと目を通しておく

選抜テーマ

テストと読みやすさ

  • ちゃんとしたテストコードは、コード自体の修正やテストの拡張にもメリットがある
  • AssertするものをWrapすることで分かりやすくできることがある
  • 言語のAssertを上手に使うとよい
  • テストの入力値は、必要なことがテストできている限り、シンプルにするのがよい
  • テストのためにコードを書くと、ロジック分割などの点でメリットが大きい
  • やりすぎはよくない
    • テストのカバー範囲を不必要に広げる
    • テスト対象のロジックが読みにくくなってしまう
    • テスト自体が開発の邪魔になってしまう

分・時間カウンタを設計・実装する

  • インターフェースの設計
    • 名前の定義から機能が読み取れるか
    • getは裏でロジックが動くと想定されないことが多い
    • クラス名・メソッド名に単位などが含まれていると読みやすくなる
  • 冗長なコメントはいらない
  • 同じようなロジックを持つメソッドは共通関数をつくって処理する
  • ベルトコンベアー設計
    • 内部的なベルトコンベアを作るためのインターフェースを作る
  • 時間バケツ設計
    • ロジックが複雑なので割愛
    • 別のクラスを含めて設計することが必要になることがある

Script to migrate ansible-vault file to single-encrypted-variable

From ansible 2.3, single-encrypted-variable is supported in addition to full file encryption.

Before this functionality was implemented, we have to handle secrets with full file encryption. With full file encryption, we can't check the diff of vault files because the whole file will be changed when adding/updating any small changes to vault file. But with using single-encrypted-variable, it's provides us transparency and make it easier to take diff and confirm the changes done(with in PRs etc..)

This script will help migrating the file based ansible-vault files into single-encrypted variable format.

for more details about single-encrypted-variable, please see following website. https://docs.ansible.com/ansible/latest/user_guide/playbooks_vault.html#single-encrypted-variable

import argparse, yaml, sys

from ansible.constants import DEFAULT_VAULT_ID_MATCH
from ansible.parsing.vault import VaultLib
from ansible.parsing.vault import VaultSecret


def main(argv):
    parser = argparse.ArgumentParser(
            description='This script will convert ansible-vault format'
                        'files to variable-based encrypted format.')

    parser.add_argument('-i', '--inputfile',
                        help='inputfile(expected vault format)',
                        required=True)
    parser.add_argument('-p', '--secret', required=True)
    parser.add_argument('--overwrite', action='store_true')
    args = parser.parse_args()

    vault = VaultLib([(DEFAULT_VAULT_ID_MATCH, VaultSecret(args.secret))])

    with open(args.inputfile, "r") as f:
        encrypted_vars = {}

        plaintext_vars = yaml.load(vault.decrypt(f.read()))
        for plaintext_var_name, plaintext_var_contents \
                in plaintext_vars.items():
            encrypted_vars[plaintext_var_name] \
                    = vault.encrypt(plaintext_var_contents)

        encrypted_yaml = yaml.safe_dump(encrypted_vars, default_style='|')

        # workaround for custom tag in yaml(!vault)
        encrypted_yaml = \
            encrypted_yaml.replace('|', '!vault |')

        print(encrypted_yaml)

    if args.overwrite:
        with open(args.inputfile, "w") as f:
            f.write(encrypted_yaml)


if __name__ == "__main__":
    main(sys.argv[1:])

Githubでforkしたリポジトリから出されたPRに修正コミットを重ねたい場合

GithubでPR出す場合、大きく分けて以下の2つの方法でPR元のBranchを作るのが一般的だと思う。

  1. オリジナルのリポジトリにtracking branchを作成する方法
  2. オリジナルのリポジトリをforkしたリポジトリにtracking branchを作成する方法

1.の場合は、ブランチをローカルに持ってきて、commit && pushしていけばいいので、今回は2.のケース。

もちろん2.の場合でも、PRをローカルにfetchしてくることはできる。

ただ、どこに向けてpushしたらいいかがよく分からない。

素人考えでは、2つ方法がありそうな気がしていた。

  1. 別のtracking branchを作成して、PR元のブランチ(fork先)にPRを出して から取り込んでもらう(2段階でマージ)
  2. 別のtracking branchを作成して、オリジナルのリポジトリにPRをPRを作成し直す

いずれの方法も1つのPR・branchとして取り扱えないので、自分が無知なばかりにイケてない使い方をしている気がして、友人に質問したら下記の情報が出てきた。

help.github.com

ほぼタイトルのまんまですが、PRの"Allow edits from maintainers."にチェックを入れておくと、(若干お行儀が悪い気がするけれど、、)フォーク元リポジトリのメインテナに限って、そのリポジトリに対してpushできるようになるらしい。

git remote addでPR元のリポジトリ追加したりの手間はあるけれど、PRの修正の手順自体はだいぶ綺麗になる気がした。

基本的にPRはPRの作成者が、レビューやコメントを元に責任持って修正するみたいなシナリオが多い気がしたので、今回こういう使い方ができることを知れたのは新鮮だった。

PlantUMLのインストール+Atom環境の構築メモ(Mac)

PlantUMLとは

PlantUMLは、簡単なテキストベースの記述から、クラス図やシーケンス図などが描くことができるツール

例えば、

Bob->Alice : hello

のような記述をすることで、下記のような図を簡単に生成することができる。

f:id:springwell:20180519220838p:plain

PlantUMLのインストール

PlantUMLを使うためには、追加でJava 8とgraphbizが必要になるので、インストールする。

Java8のインストール

https://www.java.com/ja/からダウンロードしてインストール

graphbizのインストール

brew install graphbiz

plantumlのインストール

brew install plantuml

PlantUMLの動作確認

cat > hoge.plantuml << "EOF"
@startuml
Bob->Alice : hello
@enduml
plantuml hoge.plantuml

を実行して、hoge.pngが作成できてたら成功

Atomのプレビュープラグイン

Atomでプレビューしながら作業したいのでプラグインを入れる。

qiitaなどを見ると「plantuml-viewer」を使っているものが多いけど、手元の環境ではうまく動作しなかった。 似たような「plantuml-preview」というプラグインがあったけど、こちらは使うことができた。

plantuml-previewのインストール

Preferences=>Install=>Search Packages から「plantuml-preview」を選択してインストールする。

plantuml-previewの設定

このプラグインを使うためには、PlantUMLのjarファイルの場所をプラグインに設定する必要がある。

PlantUMLのjarファイルの場所は下記のような感じで調べることができる

which plantuml
cat /usr/local/bin/plantuml
#!/bin/bash
GRAPHVIZ_DOT="/usr/local/opt/graphviz/bin/dot" exec java -jar /usr/local/Cellar/plantuml/1.2018.5/libexec/plantuml.jar "$@"

みたいになっているので、「/usr/local/Cellar/plantuml/1.2018.5/libexec/plantuml.jar」を

Preferences=>Packages=>plantuml-previewの「PlantUML Jar」の項目に設定して、

hoge.plantumlを開いた状態で、「ctrl+p」を入力して右側に表示されたら成功

簿記の勉強メモ(1)

簿記を勉強すると、エンジニアとしても磨きがかかると聞いたので、勉強してみることにした。

勉強の記録を書いていくけど、飽きたら多分やめる。

簿記

  • 取引などを帳簿に記録すること
  • 財務諸表として利害関係者に公開する

仕分け

  • 勘定科目と金額で取引を表現する
  • 勘定科目
    • 建物、現金など定められた表現が使われる

貸方と借方

  • 左側は借方
  • 右側は貸方
  • 用語としてDefineされてるもので特別な意味はないらしい

簿記の5要素

  • 資産
  • 負債
  • 純資産
  • 収益
  • 費用
  • 勘定科目は、このいずれかに該当する

資産

  • 現金、建物、土地のほか、お金を返してもらう権利などがある
  • 現金
  • 売掛金
    • 代金後払いで物を販売して、あとで代金を受け取る権利
  • 商品
    • 販売目的で所有する物品
  • 貸付金
    • お金を貸して、あとで返してもらう権利
  • 土地

負債

  • 買掛金
    • 代金後払いで商品を購入した際の、あとで支払う必要がある代金
  • 借入金
    • 銀行などから借りた返さなければいけないお金

純資産

  • 資産から負債を引いたもの
  • 資本金
  • 出資額と利益を足したもの

収益

  • 純資産を増やす要因となるもの
  • 売上
    • 商品を販売することによって得た収入
  • 受取利息
    • 預金金利や貸付金の利子
  • 受取手数料
    • 取引などを仲介して得られた手数料など

費用

  • 収益を得るためにかかった支出
  • 仕入
  • 給料
  • 水道光熱費
  • 広告宣伝費
  • 支払利息
    • 借入金に対して対して支払った利子
  • 支払手数料
    • 取引を仲介してもらったことなどによる手数料
  • 支払保険料
    • 火災保険料など

会計期間

  • 財務諸表は1年に一度作る
  • 期首
    • 会計期間の開始日
  • 期末、決算日
    • 会計期間の終了日
  • 個人商店などでは1/1-12/31が会計期間になる

貸借対照表

  • 資産と負債、純資産(財政状態)が記載される
  • 左側に資産、右側に負債と純資産を記入する

損益計算書

Low-Interaction HoneyClient: Thugを使ってみた。

某セキュリティイベントに参加してきたのがきっかけで、Thugを少しいじってみたのでそれに関するメモ。

Thugについて

Webクライアント型ハニーポット

ブラウザを模したプログラムで、Webページにアクセスすることで、その挙動について調べることができる。

インストール

docker自体のインストールについては割愛 docker.ioでdockerイメージとして配布されているのを発見したので、docker pull

docker pull honeynet/thug

コンテナの起動

docker run -itd -v {local_dir}:/logs honeynet/thug /bin/bash

{local_dir}にホストマシンのログ記録用ディレクトリを指定しておくことで、ホストマシンからもthugのログ(コンテナ内では/logs)が参照できるようになる。

thugコマンドの実行

docker attachでコンテナに接続

docker attach  {起動したコンテナID}

コンテナ内でそのまま

# thug

で実行できるかと思いきや、なぜかPATHが通っておらず

# python /opt/thug/src/thug.py

とすることでthugを実行できた。

実際にページを踏んでみる

909research.com あたりのページを参考に、

python /opt/thug/src/thug.py -FZM {URL}

を実行してみるとコンテナ内の/logs、ホストマシン上の{local_dir}に下記のようなログファイルが生成される。

{ID名}
    ├── analysis
    │   ├── graph.svg
    │   ├── json
    │   └── maec11
    ├── application
    │   ├── javascript
    │   └── x-shockwave-flash
    ├── image
    │   └── png
    └── text
        ├── css
        ├── html;\ charset=UTF-8
        ├── html;charset=UTF-8
        └── javascript

ログファイルの詳細については、今回は割愛。 analysis/graph.svgあたりの読み込みのグラフなどを見ると面白い。