ばぁど・うぉっちんぐ

セキュリティに強いWeb屋。自由と春を求めて羽ばたく渡り鳥。

このブログはGoogle Analyticsを利用しています

わたし「も」定時で帰ります。残業が多いと言われたIT業界で7年目エンジニアの考えてきた残業のアレコレ。

f:id:UltraBirdTech:20201017204644j:plain どーも。ばぁどです。

7年目エンジニアです。 新卒でWebアプリエンジニアとしてプログラムを学び、以降IT業界で仕事をしております。

個人的な印象なのですが筆者がIT業界に入った当時(2014年頃)はIT業界=残業が多い業界というイメージでした。 実際に会社の最寄りから自宅までの終電を調べてプロジェクトリーダーに報告したのを覚えています。

しかし社会人3年目頃からは幸運なことに残業などはなく基本的に定時で帰れる生活を送っております。

今回は自分の残業に対する考えと残業をしないためにやっていることを備忘録としてアウトプット致します。

※タイトルは吉高由里子さんが主演された2019年度のドラマ「私、定時で帰ります」から付けました。本当は昨年から公開しようと思っていましたが、温めすぎました苦笑

1. 残業に対する主張

基本残業はしないことが良いことだと考えています。

筆者が残業をしないことが良いことだと考えている理由は下記3つです。

理由① 貴重な社会人のプライベート時間が削られるから

一つ目の理由は残業をするとプライベートの時間が削られてしまうからです。

プライベートの時間は基本的には自由に使うことができる時間です。なんせ、プライベートの時間ですから。 そのプライベートの時間が仕事の都合で削られるのは、筆者は激しく嫌悪しております。

仕事が終わった後は、仕事のストレスを発散するために大学時代の友人と飲みにいくこともあるだろうし、業務後に自己研鑽のために資格の勉強や、技術情報のインプットをすることもあるでしょう。 それらのプライベートに「何をするか」という選択肢を、会社都合で奪ってしまう残業が筆者は嫌いです。

会社に何の権利があって、社会人の貴重なプライベートの時間が奪われているかが理解できません(暴論)

理由②どんな問題があっても残業でカバーという思考になるから

残業が発生する職場・プロジェクトは残業が発生しうる理由や何かしらの問題を抱えていることがほとんどです。

例えば、メンバーがタスクを定時内のみでこなす技術力を持っていなかったり、営業がどう考えても無茶なスケジュールの案件を受注してしまったり、そもそもタスク管理がされておらず優先順位がバラバラで全てのタスクの優先順位が高として管理されていたり、残業が発生する理由は様々だと思います。

残業とは「魔法」のようなものであり、これらの幾多の解決しなければいけない課題を「残業」という行為一つで、どんな炎上案件のタスクでも、一通り消化して最終的な結果として問題がないように見せることができます。

この世が「終わり良ければ全てよし」という考えの人だけであれば、残業でカバーしておけばいいかもしれません。 だって残業さえすれば、仕事が終わるという目標は完遂されるのですから。

しかし少なくとも筆者の個人的な考えとしては、残業が発生するということは何か解決するべき問題があると考え、残業でカバーという事象が発生することの根本原因を追及し、解決するべきだと考えます。

本来であれば、技術力不足であるならばメンバーの技術力の育成、先輩社員のサポートを行うことが具体的な解決策の一つになりえます。 無茶な工数での受注は会社としての受注する案件を見極められるように次回以降の反省点とするだったり、タスク管理の不徹底はタスク管理ツールを導入したりするなどが解決策として、それぞれあげられるでしょう。

残業が発生する課題には各々適切な解決方法があります。 それにもかかわらず、残業はそれらの課題を改善する機会を逃し、解決すべき課題を解決せずにタスクを完遂させてしまいます。

喉元過ぎれば熱さ忘れるという諺がありますが、喉元を何度も過ぎれば熱くて嫌になりますよね。

解決するべき課題は、しっかりと向き合って課題を解決しましょう(当たり前)

理由③生産性を考えないダラダラ残業ダメ絶対

生産性を考えないダラダラ残業というものがあります。

定時に家に帰っても特に予定もないから、定時が過ぎても作業をしようだったり、 普段から毎日2時間残業しているから、いつしか毎日10時間仕事をすることがデフォルトになっている方もいらっしゃるかもしれません。

その会社の就業規則にもよりますが、それらのダラダラ仕事をこなすことは、生産性という仕事をする上で大事な要素を無視した働き方になっています。

稀に定時がすぎてからが本番という考えをしている方もいるのですが、残業は周りに感染するのでなるべく控えていただきたいというのが筆者の個人的な考えです。

2. 残業代について

一応、残業について記事を書いているので、残業代がかかえている矛盾点などにも触れておこうと思います。

①残業代が抱える矛盾

残業代は給与計算において矛盾を発生させることがあります。

技術力があり定時内でタスクを終わらせることができる人と、技術力が少し足りず残業をしてタスクを終わらせた人だと、後者の人に残業代が出てしまい、本来であれば技術力がある人がより多く賃金をもらえるはずなのに、後者の残業をしている人が賃金をより多く貰うという矛盾が発生してしまいます。

技術をしっかりと評価している会社であるならば、残業代込みでも前者の人が多く賃金をもらっている状況にすることはできると思いますが、全ての状況においてそのような理想の評価制度が整っているわけではないでしょう。

残業代はこう言った給与計算における矛盾を発生させる場合があります。

②残業代で稼ぎ始める(搾取する)人たち

残業代が支払われていると、稀に残業代で稼ぎ始める人が出現します。

残業代というのは定時内で仕事を終わらせれば、本来は会社が従業員に対して支払わなくていいコストです。 それにも関わらず、定時に終わるタスクをわざと時間をかけてタスクを消化し、残業代を会社から搾取する人も稀にいます。

本来は搾取されたお金は、会社のために頑張っている本来であれば評価されるべき人に対してのボーナスだったりとか、会社の福利厚生として社員に還元することができるお金かもしれないのに、わざと残業をして搾取されてしまったおかげで取り分が減ってしまいます。

③見込残業代について

稀に企業によっては、これらの残業代の矛盾及び残業代で稼ぎ始める人を防ぐために「残業代を出さない」という選択をしている企業があります。

企業によっての規則やルールなので、企業の中で止まる話ならば別にいいのですが、筆者個人的には「残業代は基本的には出すもの」だと考えています。

理由は「突発的な残業を行なった」人が救われないからです。 仕事は全て予測可能であり、スケジュールをしっかりと組むことで残業はゼロにできると考えています。 しかし、どうしても読みきれなかったりして突発的な残業が発生することは稀にあります。 そういった稀に発生する突発的な残業をしてくれた人に対して、残業代が支払われないのはおかしいです。

後見込み残業代というのは、よくブラック企業が使う単語のイメージがあるので、筆者個人的にはあまりいいイメージはありません。

3. 残業をしないための不断の努力

残業はしたくない!!これは筆者が仕事をする上で重要視しているポイントの一つです。 ただ「残業はしたくない」という主張をするだけではいけないと考えています。

そもそも会社に所属している上で、与えられた仕事を完遂する努力義務はあります。 個人のスキル不足や、個人の責任下で行なった見積もりミスが原因で残業をせざるおえない場面が稀に存在します。 そう言った場合は、さすがの私も残業をするのですが、やはりここ数年は残業をしない生活を送ることができています。

それは日常的に残業をしないように不断の努力を行なっているからです。

①自己のスキルアップ

筆者は若手の頃(入社して2年目くらい?)から自己のスキルアップを欠かしませんでした。

若手の頃は、自分自身の技術力が不足しタスクを完遂できない場合があります。 そのような場合は通常先輩のフォローだったりとか、チーム内で労働時間が均等になるように管理するなどをして残業が発生しないようにするのが定石です。 しかしいつまでもそのような先輩やチームにおんぶに抱っこ状態だと、とても迷惑な社員です。

筆者は若手の頃、技術分野が得意な方ではなかったので、どちらかいうと足を引っ張る側の人間でした。 そんな当時の筆者が一刻も早く与えられたタスクを定時内で完遂できるように基礎的な技術を身につけることに終点を当てスキルアップを行いました。 例えば当時は8:30始業だったのですが、1時間前の7:30に出社して勉強をしたり、終業後、土日もスキルアップを欠かさず行っていました。 その結果、3年目ごろには与えられたタスクは定時内で終わらせることができるレベルの技術力を身につけることができました。

また、定時内にタスクを終わらせることができるようになってからも自己研鑽は欠かしていません。 理由はCI/CDやコンテナ技術など生産性の向上につながる技術が日々開発されているからです。

具体的にはユニットテストの自動化をしておくと特定のタイミング(Gitでプルリクエスト出した場合など)にデグレがないか確認できますし、デプロイも大切な作業ですが一々人が手でデプロイする必要はありません。

またコンテナ技術も開発環境構築の時間短縮に十分貢献できる技術でした。

これらの生産性の向上に繋がる技術を現場に用いることによって、現場の課題の解決や生産性の向上を行い残業の削減につながる場合があります。

このように残業をしないためにも不断の努力が大事というポイントもあると考えます。

②無理のない計画を立てる

自身の仕事に対するタスクを見積もり、残業をしなくても良い無理のない計画を立てています。

無理のない計画はスケジュールに余裕があるので少し突発的な作業が発生しても、定時内で消化できます。 もしくは、直近1週間のタスクを入りくりすればなんとか定時内に消化できる程度の余裕は持っています。

稀に忙しすぎて計画を立てる余裕がなくて残業まみれという方がいますが、それは計画をしていないから忙しいのです。 鶏と卵がどちらが先みたいな話になりかねないですが、計画をしないとタスクの精査、棚卸し、優先順位づけなどができず、結局忙しいままです。

一度落ち着いて、計画を立ててみるのが一番ですよね。

ちなみに、営業がとってくる無茶なスケジュールの請負案件は論外です。 (そう言った案件は強い意志を持って拒否しています)

③定時で帰る覚悟を持つ

周りが残業をしていても帰ります。 上司、先輩、同僚が残業をしていても、定時に帰ります。 空気は読みません。 「他の皆が残業しているから自分も意味なく席にいて残業をする」という同調圧力は跳ね除けます(最近のIT業界はリモートワークに移行しているみたいなので同調圧力はさほどありませんかね)

定時に帰宅するためには定時がきたら「何がなんでも席を立ち帰宅する」という強い覚悟を持つことが大事です。

最初の方は違和感を持たれる場合もあるのですが、いつしか定時に帰宅がパーソナリティにもなりえます。(当時の筆者はそう言った「定時に帰る人」という印象を周りのメンバーに与えていたようです。)

まとめ

残業はしたくありません。 プライベートの時間をなんだと思っているのだ。

筆者が若手の頃から口癖のようにいっていたのですが「残業するくらいなら、大学時代の友人と飲みに行きたいし、女の子とデートしたいし、家に帰って勉強したい」です。

これからの社会人人生でも残業が発生しないように不断の努力を続けます。

未経験からエンジニアになるために意識した「プロフェッショナルになるための10,000時間」と「石の上にも3年」について

ばぁどです。

7年目エンジニアです。 業務は主にWebアプリケーションの作成や、サイバーセキュリティ関係を細々とやっています。

約半年の内定者研修を経てWeb開発受託を主とする中小企業に新卒で入社してプログラマに育てていただきました。

それから数年が経ち、エンジニアとして何社か経験した現在では、未経験のエンジニア志望にプログラムを教える機会や外部でエンジニアになりたての人にお会いしてお話しする機会がありました。

その時脳裏によぎるのが、新人時代に教えてもらったプロフェッショナルになるために必要な時間についてでした。 今回は自分自身の思考整理も兼ねて、アウトプットしておきます。

プロフェッショナルになるために必要な時間

まず、プロフェッショナルという単語についてです。

広辞苑より

《名詞・形容動詞》それを職業として行うようす。職業的。専門的。また、専門家。プロ。

巷では、よくプロフェッショナルになるためには10,000時間が必要だと言われております。

初出は、英国の新聞記者さんの出した本だそうです。

Ten thousand hours is the magic number of greatness.

(訳:1万時間は偉大さを示す魔法の数)

本名:マルコム・グラッドウェル氏の著書『天才! 成功する人々の法則』

上記の本では、音楽系の大学生にヒヤリングを行い、総練習時間を計算してみたところ練習時間が10,000時間を超えたあたりで、10,000時間を超えている人と、超えていない人の実力に差が出たそうです。 このように10,000時間に対してヒヤリングを基にした根拠も書かれており、10,000時間というのは何かしらを極めるための一つの目標値としてはありなのかなと思っております。

この10,000時間を根拠に1日何時間該当項目について勉強や経験をすれば良いか、計算をしてみると下記のような結果になります。

1日の勉強時間 1年(365日計算) 10,000時間に到達するまで何年かかるか
3h 1095h 約9.13年
5h 1825h 約5.4年
8h 2920h 約3.4年
10h 3650h 約2.7年

1日8時間というのは一つの大きな分岐点だと思います。 なぜかというと、基本的に日本には「八時間労働制」という制度があるのでそれを基準としています。

平日8時間しっかりと仕事をして、土日も休まずに自己研鑽をすると約3.4年で10,000時間を超えることができます。

ちなみにエンジニアが休日に勉強せずに、平日の業務時間のみの場合は下記になります。 エンジニアが休日も自己研鑽するべきか?論争はよく起こりますが、参考として置いておきます。

1日の勉強時間 1年(245日/年間休日120日計算) 10,000時間に到達するまで何年かかるか
3h 735h 約13.6年
5h 1225h 約8.1年
8h 1960h 約5.1年
10h 2450h 約4.0年

※ 1日3時間、5時間労働はあまりないかもしれませんが上記表と比較するために残しました。

業務時間だけの人だと5年を少し過ぎたあたりで10,000時間に達するのに対し、休日も勉強している人は3.4年で10,000時間に達するので、両者の間には1.6年の差があることがわかると思います。

そもそも10,000時間というのが本当なのか説はありますが、休日勉強する/しないで差が出るのは分かるでしょう。

ちなみに私は前者の休日も自己研鑽することを推奨する派です。

石の上にも3年について

日本にも同じような諺があります。 「石の上にも3年」です。

コトバンクより引用

冷たい石の上でも3年も座りつづけていれば暖まってくる。がまん強く辛抱すれば必ず成功することのたとえ。

上記の説明だと、”必ず”とついてしまっているのが中々味わい深いですが、10,000時間の時に計算でもしたように毎日休まず8時間やれば、3年過ぎたところで一定の成果が出るようになります。

私自身の話になりますが、私はエンジニアになって最初から休日に勉強をするような人ではありませんでした。 平日に仕事をするので手一杯でメンタルをやられて最初の数ヶ月の土日はひたすら布団の上で平日に自動録画されたドラマ「相棒」をポテチ食べながら見る自堕落な日々を過ごしていました。

しかしこの10,000時間や、当時の部門長に残業を禁止していただけたおかげで、一刻も早く一人前になって会社の足枷になるのを止めようという思考に変わり、徐々にプライベートの時間に自己研鑽を始めるようになりました。 平日は毎朝5:30に起きて、7:30には会社に出社して勉強や技術ブログを読み込んだり、残業禁止してもらったので定時に帰って19:00から就寝時間まで勉強を続けました。 土日も資格勉強だったり、当時の会社は夏冬で開発合宿というイベントもやっていたので、そういったイベントにも積極的に参加していました。

そしてプログラマとして自信を持てるようになったのは、社会人4年目の夏くらいだったかなぁと思います。 その時には周りからの評価も一定して一人前として扱ってもらえていたイメージです。 一年目から土日の自己研鑽を欠かさなかったり、もう少し要領よく勉強していれば自信を持てるのも早かったのかもしれないですが苦笑

私の場合は石の上にも4年でしたね。

石は選ぶ必要あり!どんな石でも良いわけではない。

最後に重要なことを書いておきます。 それは石の上にも3年の説明にも書いてありましたが、”絶対に成功する”というのは決して正しくはない場合があるという点です。

自分自身が置かれている”環境”というのは、とても重要です。 環境によっては、自分の実力が100%発揮できる環境もあれば、少しも学べることがなく成長できないという環境も間違いなく存在します。 今自分自身が置かれている環境が前者であるならば問題ありませんが、後者である場合は環境を変えるための何かしらのアクションは必須です。

アクションとは大きい会社であるならば部門の配置転換を求めてみるだったりとか、転職なども一つの手段だと考えます。 結局は、今置かれている環境(石の上)でどういった経験を積んで、そのようなスキルを身に付けたいかが自分の中で落とし込めているのであれば問題ないのですが、そうでないのであれば「石のうえにただ座っているだけ」になってしまうので、どういった環境で10,000時間を過ごすかはしっかりと考えましょう。

まとめ

個人的に重要だと思うポイント

  1. 10,000時間を目安に勉強をする
  2. 下に敷く石は選ぶ必要あり

私は運よくしっかりと基礎を築ける会社でプログラマとして成長することができました。 これからも新しいことを始めるときは、10,000時間を目安に自己研鑽に励みます。

親クラスで定義した関数内において、子クラスでimportしたmoduleを使いたい!!!私はPythonを完全に理解していなかった!!!

結論

子クラスの適切なタイミング(__init__()時など)で、インスタンス変数にモジュールを入れてあげる。

とある日

下記のようなコードを打っていた。

親クラス(Parent)が持っている関数内(parent_method())で、子クラス(ChildFirst or ChildSecond)でimportしたmodule(child_first_module or child_second_module)の関数を使いたい。

目的は子クラスで import した module によって親クラスのparent_method()の 処理を変えたかった。 parent_method()は子クラスにおいて共通の処理があり、クラスによる差分はモジュール側で吸収するので親クラスで定義したい。

Pythonのバージョンは3.7.2です。

$ python --version
Python 3.7.2

ディレクトリ構成

┣child_first.py
┣child_first_module.py
┣child_second.py
┣child_second_module.py
┣main.py
┣parent.py

ソースコードの中身

parent.py

ChildFirst及び、ChildSecondが継承する親元のクラス。 parent_method()を実行すると、child_module として import しているモジュールの関数を実行できるようにしている。

class Parent():
    def __init__(self):
        # 親クラスは抽象的なクラスのため直接__init__()しない
        pass

    def parent_method(self):
        child_module().say()

child_first.py

子クラスその1。 子クラスモジュールを import している。

from parent import Parent
from child_first_module import ChildModule1 as child_module

class ChildFirst(Parent):
    def __init__(self):
        print("I am Child First Class")

child_first_module.py

子クラス1 で import されるモジュールその1。 say() 関数を持っている。Parentクラス内のparent_method()内で呼ばれることを想定。

class ChildModule1():
    def __init__(self):
        print('child module 1')

    def say(self):
        print('I am child module 1')

child_second.py

子クラスその2。以下同文。

from parent import Parent
from child_second_module import ChildModule2 as child_module

class ChildSecond(Parent):
    def __init__(self):
        print("I am Child Second Class")

child_second_module.py

子クラス2 で import されるモジュールその2。以下同文。

class ChildModule2():
    def __init__(self):
        print('child module 2')

    def say(self):
        print('I am child module 2')

main.py

単純に子クラスその1、その2を呼び出すだけのファイル。

from child_first import ChildFirst
from child_second import ChildSecond

child_first = ChildFirst()
child_first.parent_method()

child_second = ChildSecond()
child_second.parent_method()

実行結果

子クラスで import しているのだから、親クラスの持っている関数内でモジュールの関数を使えるだろうと main.py を実行したところ、エラー。 main.py の 子クラスが呼び出した親元クラスの parent_method() 実行時にエラーが起きている。

$ python main.py
child module 1
I am Child First Class
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    child_first.parent_method()
  File "/Users/xxxxx/python/Python_Practice/module_import/parent.py", line 6, in parent_method
    child_module.say()
NameError: name 'child_module' is not defined

てっきり小クラスで import した module を 親クラスで定義した関数から呼べると思っていました。 親クラスを継承した関数って、子クラスで定義したと同義のイメージだったので特に違和感なく、コードをリファクタリングしていました。

一緒に働いている同僚と一緒に雰囲気でいけると思い込んでおり、あれれ〜??となっていました。

私はPythonを完全に理解していなかった・・・・

試行錯誤した結果: 子クラスの適切なタイミングでインスタンス変数に入れる

子クラスの適切なタイミングで、子クラスのインスタンス変数にモジュールを代入してあげる。 親クラスからはselfをつけて呼び出してあげる。 今回は__init__()時にインスタンス変数に入れてあげるようにしました。

parent.py

ChildFirst及び、ChildSecondが継承する親元のクラス。 parent_method()を実行すると、child_module として import しているモジュールの関数を実行できるようにしている。 インスタンス変数に入っているのでselfを追加。

class Parent():
    def __init__(self):
        # 親クラスは抽象的なクラスのため直接__init__()しない
        pass

    def parent_method(self):
        self.child_module().say() # ★変更部分!!★

child_first.py

子クラスその1。 子クラスモジュールを import している。__init__()時にインスタンス変数を追加。

from parent import Parent
from child_first_module import ChildModule1 as child_module

class ChildFirst(Parent):
    def __init__(self):
        self.child_module = child_module() # ★追加部分!!★
        print("I am Child First Class")

child_second.py

子クラスその2。以下同文。

from parent import Parent
from child_second_module import ChildModule2 as child_module

class ChildSecond(Parent):
    def __init__(self):
        self.child_module = child_module() # ★追加部分!!★
        print("I am Child Second Class")

実行結果

$ python main.py 
child module 1
I am Child First Class
I am child module 1
child module 2
I am Child Second Class
I am child module 2

そうそう。やりたかったのはこの挙動。 本当にこれでいいのか?という説はあるが・・・ インスタンス変数として定義してあげれば、インスタンスからアクセスはできるので、これでいい気がする。

子クラスでimportしたmoduleインスタンス変数に入れずに呼び出すことができるので、親クラスから呼び出す時も同じ感覚でいたのが勘違いの原因かなぁ。

何か挙動で変なところが出たり、今後のクラス設計で足を引っ張らなければいいのだが・・・

まとめ

なんかPythonの基本的なところでつまづいてしまっている気がする。 Pythonの基礎本(錦蛇のオライリー本)、カッコつけてカナダに行くインターン生にあげちゃったんだよな・・・苦笑

しかし、これで・・・ Python 完全に理解した!!(嘘

「ねだるな、勝ち取れ、さすれば与えられん」。新人プログラマ時代に教えてもらった今でも心に刻まれている言葉たち

「ねだるな、勝ち取れ、さすれば与えられん」

ふと、先日会社の後輩と雑談していて、思い出したのが上記の言葉でした。

筆者が新人時代に上司から与えられた言葉の一つです。

新人時代、筆者はダメダメなエンジニアでした。 プログラムの文法を記号としてでしか認識できておらず、関数の戻り値を変数で受け取るということすら理解できておらず同期に驚かれた覚えがあります。

そんな筆者が新人時代に配属された部署の上司に教育していただき、今でも心に刻んでいる言葉があります。 せっかく思い出したので、備忘録として残しておこうと思います。

「ねだるな、勝ち取れ、さすれば与えられん」

自分がやりたいと思った仕事は「やりたいな」と思っているだけでなく行動に起こして、どう自分から勝ち取りに行けるか?を考えて行動しなさいという意味で受け取っております。

この言葉の初出は「パトレイバー」というアニメ作品だそうですね。 筆者はアニメには疎いので、上記アニメは全く知らなかったのですが言葉だけ託されてきました。

振り返ると、情報処理安全確保支援士になってから数ヶ月。 転職して数ヶ月しか経っていないのですが、サイバーセキュリティの仕事につきたいなと思い始めて、そこからセキュ塾というセキュリティの専門学校(のようなところ)に通いました。

これらの行動は全てサイバーセキュリティの仕事をやってみたいと思うだけではなく、自分から勝ち取りに行くために行動に移した結果だったのだろうと振り返ることができます。 結果、無事にサイバーセキュリティに関する業務を行なっている会社とご縁があり、今はサイバーセキュリティに関する仕事に従事することができております。 要は勝ち取ることができ、与えられたんですね。

新人時代にこの言葉を教わったからこそ、今の自分があると言っても過言ではない言葉です。

怠惰を求めて勤勉に至る

これは麻雀か何かの漫画だったんですかね?

「自分が楽したいなと思い、どうすれば後々楽になるかを考えると本当の怠け者は勉強をするようになる」という少しユーモアのある面白い言葉です。

確かこれを教えていただいたのは、新卒プログラマの冬休み明けくらいだったかな・・・ 当時はまだ休日に勉強なんてありえない。プライベートは休むためにあるので、仕事を思い出す勉強なんてやりたくないなと怠けていた時期でした。 土日の使い方なんてポテトチップスを食べながら平日の昼間に再放送されている相棒の録画を見るという生活を送っていました。

上記でも言った通り筆者は新人時代、同期と比べてプログラムのスキルが劣っておりました。 そんな時にこの言葉を聞いて、本当に怠けたいのであれば将来困らないように少しでも勉強しようと思い、少しずつプライベートの時間で勉強をしたのが始まりだったと記憶しています。

また筆者は朝型の人間であり、毎朝始業開始の1時間前に会社に出社して勉強をしていた時期もあります。 こう言った努力も将来的に少しでも楽をしようと思い、努力を少しずつ始めた結果だと思います。

ちなみに筆者は現在も技術者としてまだ怠けることができる段階には至っておらず、勉強の日々は続いています(おそらく永遠に怠けられる日は来ないのでは?)

やってみせ、言って聞かせて、させてみせ、褒めてやらねば人は動かじ

有名な第二次世界大戦時の軍人山本五十六の語録です。 人の教育をするにおいての基本ですね。

この言葉は教えられたというよりは、先輩社員のデスクトップの壁紙か何かで「良いことが書いてあるな。なんなんだろう?」と思って調べたのがこの言葉に出会ったキッカケでした。

もう7年目になっているので技術指導を後輩にする立場にあるのですが、 言葉足らずで後輩が理解し切れていないなと感じたら、すかさず画面を共有して実際に見せるようにしています。 また時間的に余裕があれば、その後に実際にやってもらうところまでワンセットです。

大学時代に教員免許の勉強もしていたので、やはりこう言った教育系の言葉は記憶に残り、今でも後輩教育・指導をするときは自然に頭に過ぎる言葉の一つです。

急がば回れ

技術研鑽は「急がば回れ」だと教わりました。

Webフレームワークを扱っていて分からないことがあればググって一番最初に出てきたSEO対策されているブログを参考にして、記述して終わりという場面はエンジニアであれば誰もが経験したことがあると思います。

しかし、本当にエンジニアとしてスキルアップしたいのであれば「基礎をしっかりとしなさい。そういう時こそ急がば回れだ!」と何度も教えていただいた記憶があります。

サッと検索して出てきたブログに書かれてある小手先の解決方法ではなく、もっとベースとなる知識を習得したうえで対応した方がエンジニアとしての伸び代がグッと長くなるということですね。

例えばRuby on Rails で Webアプリケーションを作成している時に Rails のみの上っ面の知識だけでなく、元の言語である Ruby の言語仕様だったり、ORM が出力しているSQLだったり、そう言ったIT技術者として基本的な技術を勉強した方が、初心者としては有益な知識になりますよね。 Rails などの Webアプリケーションフレームワークは それらの基礎的な技術の上に構築されているものなので、ベースとなる基礎知識が築かれていないと、どうしてもその場しのぎの対応になります。

仕事では成果を出さなきゃいけないのは当たり前なのだが、エンジニアとしての成長を第一に見るならば小手先の対応力ではなく、ベースの技術をしっかりと築くことが大事だと、この言葉で教わりました。

まとめ

受け取ったバトンは次に渡す必要があります。 筆者もIT業界に飛び込んでもう7年目。 何人か面倒を見なければいけない後輩がいます。 その彼らに適時、これらの言葉を伝えようと思います。

社会人1年目の時に教わった「エンジニア」が「プロフェッショナル」として働くということ

どーも。ばぁどです。

藤井聡太棋聖がすごいなーとニュースを見て感心しております。

その藤井聡太棋聖の影響で将棋に少しハマっており、同様にプロの将棋棋士である香川愛生女流棋士YouTubeとか見ている4連休を過ごしています。

YouTubeを見ながらやはり将棋は面白い、奥が深いなー、(香川愛生女流棋士可愛いな)と思いつつ、将棋棋士のプロとしての姿勢を感じさせる部分もあり、ふと筆者が社会人1年目の時に教わった「エンジニアがプロフェッショナルとして働くということ」を思い出しました。

最近仕事中にこのプロフェッショナルとして働くということを考えることもあり、文章として自分の考えをまとめておこうと思いブログを書いております。

Who are you?

社会人7年目のITエンジニアです。

Webプログラムが得意であり、Ruby, Pythonが大好き。 またセキュリティエンジニアとしての知見も持っており、セキュリティ×Webアプリエンジニアというエンジニア像を追いかけています。

プロフェッショナルとは?

広辞苑より

《名詞・形容動詞》それを職業として行うようす。職業的。専門的。また、専門家。プロ。

広辞苑には、このように専門的な技能を持って仕事をしている人のことを指しているようです。

ITエンジニアとしてのスキルは、専門的な知識だと考えます。 理由としてはプログラムの構文だったり、ネットワークの知識は、大学で教わったり、専門書を読んで身に付けるような、専門的な知識ですよね。 アメリカであれば、IT系の大学における学歴がなければプログラマとして働けなかったり、最近日本でもプログラムスクールなど、専門的に学ぶような期間が増えている印象があります。 HTMLなどは高校で教えたりすることはありますが、ITエンジニアに必要な知識は決して一般的に常識的なレベルの知識ではないと考えます。

故にITエンジニアに必要な知識は、職業的に専門的な知識だと言っても良いと考えます。

エンジニアとしてのプロフェッショナル

個人的な考えになります。 個人的な考えとして、エンジニアがプロフェッショナルになるためには下記要素があると考えます。

  • 1日に終わると思われるタスクを、見積もり通り1日で終わらせることができること

一般的な1人前と言われるラインとして引かれているのはこのラインなのではないでしょうか? 先輩やリーダーから1md想定で渡されたタスク、自分で見積もって1mdで終わるなと思ったタスクをしっかりと見積もった範囲内で終わらせることができることはとても重要な能力だと思います。

この1mdで終わらせるという能力の中には複数の技能が必要だと考えます。

例えば、Webアプリケーションフレームワークを扱い画面を作成できる技術力。 このためにはWebアプリケーションフレームワークがどのようなルールでルーティングを行い、画面に描写しているかなどのルールを把握している必要があります。また、プログラム能力でも初歩的なところで躓きすぎないというのが重要です。

また、今までの経験からどこに落とし穴があるかを見極めて工数を見積もるという高等テクニックも割と重要になってきますね。

個人的な考えになりますが、1mdのタスクを1mdで終わらせることができるためには、3年ほどかかるのかなという感覚です(石の上にも三年と言いますし・・・)

  • エンジニアとして必要最低限の最新技術を常に情報収集していること

IT業界あるあるなのですが、IT業界の時代の移り変わりはとても早いなと感じております。

例えば、筆者が新人時代はちょうどソースコードの管理でGitがスタンダートになろうとしていた時期だった認識です。当時はまだコード管理はSVNだったかな・・・ それだけでなくCI/CD、aws、仮想化技術(docker)が立て続けに出てきたイメージがあります。

今では、これらは個人的には当たり前の技術であり、Webアプリケーション開発を行う上で必須の知識だと考えております。

理由としては、開発案件の受託だったりとか、準委任契約でお客様先で働くとなっても、これらの最新技術に関しては共通言語として会話ができるようになっている必要があるからです。

例えば、常駐先で必要なスキルとしてDocker上での開発があるにも関わらず、Dockerという単語を知らないというレベルだと、まずはコンテナ技術に関する知識の吸収から必要であり、お客様が求めているレベルのサービスを提供できているとは言えないと考えているからです。

やはりこれらの技術は、能動的に知識を拾いに行こうと思わなければ、身に付けることができない知識です。 筆者もCI/CDの概念を必死に理解しようと新人時代に悪戦苦闘したり、aws、dockerに関しては自分で本を買って勉強をしました。(awsに関してはキャッチアップ遅れ気味です。。。反省)

ただ、常に最新の技術を扱えるようにしておくのではなく、アンテナを貼って業務で必要になった時にすぐにキャッチアップできるようにしておけば良いのかなと思っております。

エンジニアがプロフェッショナルとして働くのであれば、これらの最新技術に関する最低限のキャッチアップは必須でしょう。

プロフェッショナルであり続けるためには

エンジニアがプロフェッショナルであり続けるためには、日々の自己研鑽が重要だと考えます。

技術の流れが早いIT業界において、エンジニアがプロフェッショナルとして働くためには日々の自己研鑽を怠ることはできないです。

最初に筆者に対して、エンジニアのイロハを教えてくれた上司には、プロフェッショナルであるためには日々の自己研鑽を怠ってはいけないと教わりました。

よくメジャーリーガーのイチローを例としてお話をしていただけました。

プロ野球選手として観客からお金をもらうのは試合の時間。 試合の時間に素振りをしても、それは給与としては認められない。 だからこそ、試合以外の時間で自己研鑽(バットの素振りなど)を行い、試合の時間で最高のパフォーマンスを出せるようにする。

まさにその通りです。 イチローさんは昨年現役を引退されていますが、今でも色々な企業に呼ばれて名言を残してくれています。 やはりとても勉強になります。

これがエンジニアになると、お客様/所属している会社からお金をもらうのは業務時間になります。 業務時間に技術の勉強をしても、それは業務としては認められない。 だからこそ、業務以外の時間で自己研鑽を行い、業務時間で最高のパフォーマンスを出せるようにする。

イチロー選手で下記のような有名なやりとりがあります。

記者:「なんでそんなにストイックにできるんですか?」
イチロー:「僕いくら貰っていると思っているんですか?」

このイチローさんの新者に対する返しが非常にクールですよね。 早くこの返しができるようになるくらいまで、給与をあげたいです。

またこのプロフェッショナルの考えに関連することになりますが「お金をもらいながら勉強をしている」状態はプロフェッショナルだとは考えておりません。

理由は業務中は勉強ではなく、成果を上げる時間だと考えているからです。 とは言え、やはりエンジニアにはこう言った「お金をもらいながら勉強をする」タイミングが必要な場合もあるというのも知っております。

例えば新卒入社の会社における新人研修中だったり、未経験からの転職エンジニアだったりすれば、研修が充実している会社に入った場合は、このような「お金をもらって勉強をする」タイミングは少なからずあるでしょう。

ただ、その場合は現状に甘んじるのではなく、一刻も早くプロフェッショナルではなくとも一人前になれるように努力はしたほうがいいかなと考えております。

「お金をもらって勉強をする」状態は、一人前ではないため出される給与も満足いくものではないことの方が多いかなと思っております。

プロフェッショナルは対価としてお金をもらいます

プロフェッショナルとして働く場合は対価としてお金をもらいます。 これは当たり前です。 レストランに行ってお金を払わずにご飯を食べるなんてことはあり得ません。

だからこそ、筆者は大学時代の友人にWebサイト構築の相談などを受けますが、相談を超えて実際に手を動かす時はしっかりと対価をいただくことにしています。 友人だからといって自分が7年間自己研鑽した労力を無償で提供するのは、7年間努力を続けた自分に対する裏切り行為ですね。

芸術家のピカソの逸話としてもありますよね。

ピカソが30秒で描いた絵に100万ドルの値段をつけました。
その理由としてピカソは、「この絵を描くために使った時間は30秒ではない。30年と30秒だ。」と言ったそうです。

(逸話は30年が40年だったり、値段が100万ドルではなく1万ドルだという諸説あります)

この逸話は本当にその通りだと思っています。

私も今年7年目になり、後輩や部下を持つようになりました。 7年間まともにやっていれば、プログラムの表面的な問題であればエラー文などを見れば一瞬で解決するのですが、後輩や部下に驚かれる場面があります。

そりゃ。そうですよね。 僕、真面目に7年間エンジニアをやってきたつもりですもの。 fizzbuzzだろうが、どんな簡単なアルゴリズムであれ、そのコードにたどり着くために要した時間は、僕にとっては7年間 + 所要時間です。

全てのエンジニアはプロフェッショナルであるべきなのか?

個人の自由だと思います。

決して常に自己研鑽を行う必要はなく、最新の情報をキャッチアップする必要はないと思います。

あくまでこのエンジニアとしてのプロフェッショナルは個人的な考えです。

決して誰かに押し付けるつもりはありません。

それに常に自己研鑽を行うことができる環境や、キャッチアップができる状態に全ての人がいる訳でもないと思っています。

人生には様々なイベントが起きます。 結婚、子育て、etc...

そんなライフイベントが起こっている中、独身時代と同じ時間を確保して勉強するなんて無茶振りだと考えます。 自分が納得できる範囲で、プロフェッショナルとして自覚をもち努力を続ければいいんじゃないですかね。

努力の量は他人と比較するようなものではないです。 結局は個人の自由だと思います。

プロフェッショナルでもミスはするよ

ここまでつらつらとプロフェッショナルであるためにはと偉そうに語りましたが、プロフェッショナルでもミスはします。 人間なのでミスをしない人なんていません。 たまにここを勘違いされている方がいらっしゃるので困ります。

プログラムでバグはつきものですし、 リリース手順を間違える事はあるし、 DBのデータを吹っ飛ばすこともあります。

そう言った人為的なミスを少なくするためにミスをしないような仕組みづくりや、ミスの影響を極小化するなどが、プロフェッショナルとしての仕事になるかなと思います。

これらのミスを防ぐためにも近年のエンジニアリングの流れがあるんですよね。 Gitを用いたプログラムのコードレビューを行いましょう、 リリース手順をできるだけ自動化しましょう(CI/CD)、 DBが壊れた時でもすぐに再構築できるように仮想化技術、コンテナ技術を用いましょうなどがあるんですよね。

やはりミスをなくすというためにも、日頃のアンテナをなるべく広げて最新情報のキャッチアップをすることは忘れてはならないですね。

とはいえ、ミスをするときはミスするよ!人間だもの!

つい数年前のことですが、受託開発でWebアプリケーションを開発していた時のお話です。受託開発であったにも関わらず明示的に仕様書を作成しなかったという案件がありました。色々と理由があり仕様書を作成しなくてもお客様先と仕様が握れていると勘違いしてしまったのですね。

しかし、そんなことはなかった。 人間の記憶というのは曖昧なもので急に仕様に関する掌返しが起こるんですね。 開発側として当時話した資料や議事録を突き合わせて説明をしても、結局Webアプリケーションの画面に大幅な仕様変更を行うことになり開発スケジュールにそれなりの影響が出てしまいました。

やはり仕様書って重要なんだなと痛感したお話でした。 仕様書を作るなんて本当に基本的なことなのに、その程度の基本的なことをやらないという痛恨のミス。 あの時は私より10年以上経験のあるベテランの人と一緒に大反省会を開きました。 次からは絶対仕様書作ります!!(固い意志)

ミスはするんです。だって人間ですもの。

まとめ

少し自意識過剰かもしれませんが、7年間IT業界で仕事をやらせていただいており、プロフェッショナルとして働かせていただいている自負があります。

また本記事で書いたことは、あくまで個人的な考え方であり、この考え方を周りに押し付ける気はありません。 ただ、私はプロフェッショナルという自覚で働いている以上、無償で働くということは絶対しませんし、プロフェッショナルとして働き続けるためにも自己研鑽を怠ることはしないように日々精進していこうと思います。

本記事は最近自己研鑽のモチベーションが持たなかったため筆者への発破を含んでおります。

モチベーション下がるときだってありますよね!人間ですもの。

4連休も終わることだし、心が折れない程度にまた頑張ろうと思います。

情報処理安全確保支援士のオンライン講習Cを受講してみた話

情報処理安全確保支援士3年目になりました。

情報処理安全確保支援士の講習は、毎年GW前から開始していたのですが、2020年度は情報処理安全確保支援士に関する法律の改正があったため少しタイミングが遅れて5月後半からの申し込み/実施でした。

講習A、講習Bの感想は下記です。 ultrabirdtech.hatenablog.com

ultrabirdtech.hatenablog.com

講習Cの内容

毎年、講習内容は見直しが入るみたいですね。 本年度は下記のテーマが個人的にはとても興味を持てました。

特にSOCチームの平常時、インシデント対応時のフローに関しては、一時期仕事としてインシデントレスポンスに関する教育を行っていたので、資料の作り方などとても勉強になりました。

平常時の対応

SOCチームにおける平常時の対応について学びました。

なんだかんだ平常時にどれだけ準備ができるかにかかっていますよね。

平常時にどれだけセキュリティ製品の検知率を高めて、緊急時対応のフローを事前に定めておくことができるかはとても大事です。

インシデント対応の全体プロセス

SOC チームにおけるインシデント対応時のプロセスを学びました。 インシデント対応の定型的なプロセスってなかなか内部にいても把握できないみたいなんですよね。

倫理と法令、契約

情報処理安全確保支援士が持つべき倫理と法令、契約についてです。 実際は倫理で 1 テーマ、法令、契約がセットで 1 テーマです。

倫理は2年目の講習Bにもありましたが、やはり毎年見るサイバー犯罪を見ると技術者は倫理が求められるんだなと痛感します。

法令、契約に関しても情報処理安全確保支援士が法律上どのような定義がされていて、どう言った役割が求められているかなどを学びます。 個人的に特に勉強になったのが、民放改正です。

2020年は民放改正のタイミングとかぶったので、請負や準委任契約などの法律が変わったことは本講習で知りました。 立場的にメンバーの契約なども気にしなければいけない立場にいるので良いきっかけになりました。

感想

講習内容にもよるのですが、インシデント管理などは個人的に興味、知見があったところだったので楽しめました。

あと残すは集合研修なのですが、新型コロナの影響で受講日の予定が立たず。。。 早く集合研修も受けてみたいです。

フィッシングサイトを構築できる SocialFish を使ってみる

本記事に書かれていることは決して悪用しないでください。 本記事に書かれている内容を使用して不都合が起きたり、何かのトラブルに巻き込まれた場合でも筆者は一切責任を取りません。筆者は情報処理安全確保支援士であり、自己研鑽のためこれらの技術に触れ傾向と対策を勉強しております。

SocialFIshとは

Educational Phishing Tool & Information Collector

フィッシングツールを学ぶためのものです。 また情報を収集するためのツールとして役立てることができます。

Python で書かれています。

github.com

フィッシングとは

人間の脆弱性を悪用してくる攻撃手法です。 主に人を騙すことで、秘匿情報であるWebへのユーザー名やパスワード、銀行の暗証番号やクレジットカードの番号などを盗み取ろうとします。

例えばフィッシングメールや、フィッシングサイトのことを指します。

ダウンロード(git clone)

$ git clone https://github.com/UndeadSec/SocialFish.git
Cloning into 'SocialFish'...
remote: Enumerating objects: 1203, done.
remote: Total 1203 (delta 0), reused 0 (delta 0), pack-reused 1203
Receiving objects: 100% (1203/1203), 14.75 MiB | 1.43 MiB/s, done.
Resolving deltas: 100% (522/522), done.

下準備( pip install)

$ python3 -m pip install -r requirements.txt 

実際に使ってみる

python3 SocialFish.py [username] [password]

$ python3 SocialFish.py [username] [password]


                          '
                        '   '  UNDEADSEC | t.me/UndeadSec 
                      '       '  youtube.com/c/UndeadSec - BRAZIL
                 .  '  .        '                        '
             '             '      '                   '   '
  ███████ ████████ ███████ ██ ███████ ██       ███████ ██ ███████ ██   ██ 
  ██      ██    ██ ██      ██ ██   ██ ██       ██      ██ ██      ██   ██ 
  ███████ ██    ██ ██      ██ ███████ ██       █████   ██ ███████ ███████ 
       ██ ██    ██ ██      ██ ██   ██ ██       ██      ██      ██ ██   ██ 
  ███████ ████████ ███████ ██ ██   ██ ███████  ██      ██ ███████ ██   ██ 
      .    '   '....'               ..'.      ' .
         '  .                     .     '          '     '  v3.0Nepture
               '  .  .  .  .  . '.    .'              '  .
                   '         '    '. '      Twitter: https://twitter.com/A1S0N_
                     '       '      '       Site: https://www.undeadsec.com
                       ' .  '
                           
Go to http://0.0.0.0:5000/neptune to start
 * Serving Flask app "SocialFish" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

http://0.0.0.0:50000/neptune にアクセスした結果

f:id:UltraBirdTech:20200329151618p:plain

ユーザー名、パスワードは起動時に指定したものが入る。

ログイン後

QRコードやアクセストークンを確認できるので、これを Config.py に記載する必要がある。 f:id:UltraBirdTech:20200329152330p:plain

core/config.py

  1 # COMPRESS APP ------------------------------------------------------------------------------    --------------------
  2 COMPRESS_MIMETYPES = ['text/html', 'text/css', 'text/xml', 'application/json', 'application/j    avascript']
  3 COMPRESS_LEVEL = 6
  4 COMPRESS_MIN_SIZE = 500
  5 # -------------------------------------------------------------------------------------------    --------------------
  6 # LOCAL CONFIGS------------------------------------------------------------------------------    --------------------
  7 DATABASE = "./database.db"
  8 url = 'https://github.com/UndeadSec/SocialFish'
  9 red = 'https://github.com/UndeadSec/SocialFish'
 10 sta = 'x'
 11 APP_SECRET_KEY = '★ここに記載する★'
 12 # -------------------------------------------------------------------------------------------    --------------------
~                          

GitHub のフィッシングサイト

f:id:UltraBirdTech:20200329152822p:plain

画像のようにフィッシングサイトとしてコピーしたいサイトの情報を入力します。 左がコピー元のURLで、右側が情報入力後に遷移する先のURLです。(基本はどちらも同じで大丈夫) ログインURLを入力した後に雷アイコンをクリックすると、同IPアドレス上にGitHubのフィッシングサイトが立ち上がる。

f:id:UltraBirdTech:20200329153000p:plain

試しに ユーザ名: test, パスワード test でログイン処理を行ってみると、リダイレクト後として設定している https://github.com/login に遷移する。

情報の搾取が成功すると画面下部にログが表示される。 f:id:UltraBirdTech:20200329153431p:plain

「VIEW」をクリックするとフィッシングで得られた情報を取得することができる。 f:id:UltraBirdTech:20200329153516p:plain

テストで入力したユーザー名:test , パスワード:test を取得することができた。

あー。。。これは悪い。

おまけ・フィッシングサイトに対する対策法

なんか、対策をしっかり書いておかないと逮捕されそうだったので

フィッシングサイトに対する対策を列挙します。

1. URL欄を確かめる

フィッシングサイトに対してはURLをしっかりと確認することが重要です。 下記画像の赤枠部分ですね。 本来であれば、GitHubは [ github.com/login ] というのが、ログインのURLになります。このURLを確認した上で、正当なログインページかどうかを確認する必要があります。 f:id:UltraBirdTech:20200329153945p:plain

ただ、気をつけて欲しいことは攻撃者は我々を騙すために似たようなURLを取得してくること。例えば GitHub なのであれば、i を 1にしたりですかね。例(g1thub.com/login

また、合わせて偽ページだと思わしきWebページの証明書の確認もしておくと良いでしょう。

下記は実際の GitHub の証明書です。正規のWebサイトであれば下記のような証明書を確認することで、フィッシングサイトかどうかを見分けるためのヒントとなります。 f:id:UltraBirdTech:20200329154159p:plain

2. 送られてきたURLを安易に開かない

一般的にこれらのフィッシングサイトへ誘導するURLはメールなどで送りつけられてきます。 いわゆる標的型攻撃の対象となってしまった企業に所属している従業員のメールアドレスに大量にフィッシングサイトへ誘導するようなメールを送り、情報を搾取しようとします。

メールだけでなく、不特定多数の人が投稿できる掲示板や、SNS(TwitterFacebookなど)に投稿されているURLなども気をつけたほうがいいでしょう。

3. 多要素認証を設定する

※ユーザー名、パスワードが盗まれた時のみの対策です

フィッシングサイトに対する直接的な対策にはなりませんが、フィッシングによってユーザー名、パスワードを盗まれてしまった時の一時的な対策にはなります。

例え盗まれたユーザー名、パスワードで攻撃者がログインしようとしても、認証する要素を追加しておくことで不正ログインを防ぐことができます。

最近のWebサービスですと、新しい端末からログインが施行されようとした場合登録済みのメールアドレスへ通知するような機能を持っていたりするので、多要素認証で食い止めている間に早急にパスワードを変更するなどの対策が必要です。

まとめ

  • SocialFish はフィッシングサイトを立ち上げるためのツール
  • 悪いことに使っちゃダメ絶対!