SIerを退職しました

あなた誰?


@kurobaraと言います。
SIerとして勤めていました。
AppEngineやAndroid、サーバサイド(インフラ込)なことをしているエンジニアです。
RubyやGoとかが好きです。
勉強会だとYokohama.rbやKyotoGDGとかによく出没しています。
その他、気が向いた(その場で触ってる技術)勉強会に行ったりしています。

はじめに


2013年8月31日付けで、新卒で入社した会社を退職しました。
2010年の入社から数えて3年半、社会人としてのマナーや基礎知識、技術系知識を教えて頂けました。
お世話になった皆様、本当にありがとうございました。

退職理由は、言語化しづらい感じがするのでダラダラとこれまでのことを書きます。
正直、何でなの?と思われることかもしれないです。
普通のことかもしれませんが、ジレンマに感じる人もいた
ということだけ理解していただける感じでお願いします。
決して、憂さ晴らしという形で書いているわけではありません。
ご理解とご了承をお願いします。

出来事と心境


ツラツラとあったことや覚えている範囲で当時思ってたことを書き下して行きます。

大学時代

サーバサイドアプリ(学生向け+自分用に簡単なWebサービス)を作っていました。
プログラムを書くことは好きでしたが、
ベンチャー企業とかでアルバイトをしているわけではありませんでした。
(恐らく、当時のプログラムで叩きだした実績のお陰で入社できたのだと思います。)

内定まで

当時(今も仕事上変わりませんが)の自分ですがjavaでバリバリ書いてました。
当時の私は、フレームワーク「Wicket」を使ってサーバサイドアプリを書いていました。
こんな経緯もあったので、以下の理由で内定を承諾したと思います。

  • Javaに強い方々(@uehaj,@nobeans)がいるらしいので、自分もその人と同じようにできるかもしれない
  • なんだかんだで、会社がいい(NTTグループなので)から安定している生活ができるかもしれない
  • (当時?)Wicket使いの人(@yamkazu)もいるから、wicket使ったりでなんか色々できるんじゃね?
  • 技術的なことができるんじゃないか

とか考えていたと思います。
よくも悪くも生活安定第一の志向を持った普通の就職活生でした。
(当時は、売り手市場だったのが、リーマンショックの影響が出ていた時期でもありました)

内定後

Kyoto GTUG(今のKyotoGDG)で開催されたGoogle AppEngineのハッカソンに参加しました。
卒論テーマにも関係もあるので・・・という軽い気持ちの参加だったと思います。
(単純にAppEngineの情報が欲しいという側面もあったと思います。)

今も関東でお付き合いがある「@dddaisuke」さん、「@fushiroyama」さんに出会いました。
ハッカソン後の懇親会でじっくり話す機会があり、そこで何か色々話したと思います。
(大学生であることややってることとか将来的な話とか・・・)

お二人にとって取り留めのないことだと思いますが、当時の自分の考えに衝撃があったと思ってます。
# 当時の自分(大学生にしては技術力高いなど)にとって褒められたとかもあったはず。。。

なので、お二人とハッカソンが無ければ今の自分はいないと思います。
(人生の転機の出会いかもしれないですね。)

#因みに、ハッカソンの結果は二位でした。

以下のこともあったので、余計に自分の考えや行動もギークよりに変わってきました。

  • KyotoGTUGのハッカソンの結果が良かったこと
  • ハッカソン後にあったKyoto GTUGのイベント(AndroidハッカソンやOSC Kansai)で色々やらせていただいたこと
  • 関東の勉強会への参加(ここで出会った@shin1ogawaさんに後々まで覚えられてたw)
入社してから

さて、入社してからなのですが様々なことを学ばせて頂きました。
そこで、技術面と仕事面という2つの面で書きたいと思います。

技術面

今思うとですが、主軸となる技術とそれ以外の技術という形の方針だったのかなぁと思います。

  • 主軸:AndroidとAndroidで活用している周辺技術
  • それ以外:Linux,Web系(サーバサイド)、その他ツール類

大きく分けるとこんな感じでしょうか・・・。

幸いなことに、他の同期と比較してプログラムはさせて頂いたほうだと思います。
特にAndroidに関しては、プロダクションレベル(一般公開しても恥ずかしくないレベル)のものを実装できました。
@korodroidさん,@sumio_tymさん、どうもありがとうございました。

また、時には意見の衝突も行いながらも寛大な心で受け入れて頂いた皆さんありがとうございました。

あとは、社内の技術勉強会でも数回(1回はメイン!!)発表させて頂けたこともステップアップに繋がったと思います。
@suzukimaさん、@yamkazuさん、ありがとうございました。

さて、ここまで良かった話なのですがどうにもしっくりこなかったところになります。

何かというと、「Android周辺技術しか」できていないことです。

これが自分にとって一番キツイ点でした。(人によってはハッピーかもしれませんが)

上記にも書きましたが、元々web系、それもサーバサイド技術まわりを中心にやって来ました。
その為、自分としては以下のような思いがありました。

  • サーバサイド周り中心の技術に強くなりたい
  • サーバサイド周りをメインでやっていきたい
仕事面

「製造工程」をメインに担当し、SEという肩書きながらプログラミングをかなりさせていただきました。
加えて、中堅(大手かも)SIerで実施する工程は大体をやらせて頂けたと思います。。。
世間一般に「SIer(特に元請け)の人間は技術力がない」という様な事が言われていますが、
幸いにも自分が配属された部署には技術に明るい人(@nobeansさん,@sumio_tymさん,@korodroidさん)が多く学ぶところは大きかったです。

2年目からその方々との会う機会が減りましたが・・・

また、理解度が高かった上司と先輩も良かったことではないかと思っています。

あまり声を大きくしたくはないですが、所謂炎上状態のPJも経験しました・・・
辛い中でも色々出来たので、今ではいい思い出です。

さて、経験の話以外に常々感じていたことピックアップして残したいと思います。
願わくば、こういうことを思うような人が出なければと思います・・・

  • 仕事をしている人達が、「楽しくなさそうしている人が多いな」と感じた(ギャップに近いところ)
  • 「政治的な理由」で制限が多くなってしまうこと
  • 後が大変なことが多々あったりしたこと
  • 資料を説明するための資料をつくること

思っていたことに加えて何よりも辛かったのは、時間がめちゃくちゃに減ったということです。

このままだと技術者として取り残されてしまうのではないかという焦りが出てきましたし、
事実、取り残され始めたという形容し難い感覚を感じていました。

最終的に・・・

キッカケとなったことは、以下のものです。。。

  • 他のエンジニアと交流し、自分が何をしたかったのか考えなおしたこと
  • GoogleI/Oに参加し、様々な国のエンジニアと話をし交流してきたこと
  • @dddaisuke」さん、「@fushiroyama」さんと飲んだこと(これまでのことを話ました)

# GoogleI/Oで世界中のエンジニアに色々言われました(- -;)
# 自分や自分の持つ能力を詳しく知ってるエンジニアは言うことが鋭いですね^;;

言われるまでも無く、自分としても思うところがあったのは事実です。
進むべきキャリアもどうしようかと上司や周りのエンジニアに相談もしていました。

上記の思うところやキッカケで起こった内容をじっくり考え直してみたら、
自分にとって最良の道は、外に出たほうが良いだろうと考えました。

# 最終(寧ろそこからが大変ですが)的な目標も到達するためにもというところもありました。

最後に


SEとしての生活は、必ずしも良かったことばかりとは言い難かったです。
ですが、ここで学んだことは後々、自分にとってプラスになると思っています。

周りの皆様(同期含む)からの期待(これから支えていって欲しいという)を感じる中で
このようなことになってしまい申し訳ありませんでした。

特に、自分を育成して頂きました「@sumio_tym」,「@korodroid」のお二人に大変感謝をしております。

選択した道に後悔が無い様、自分の信じた道を進んで行きたいと思います。

最後になりましたが関係者の皆様、
今まで本当にありがとうございました。

iTerm2のMetaキーを変更する

はじめに


MetaキーはEmacsライクのように使いたい人です。
変更と書けば物凄く大げさな内容です。

変更方法


iTerm2の環境設定で変更します。

  1. Profiles
  2. Left option key acts asで+Escを選択
  3. Right option key acts asで+Escを選択
  4. 閉じる

これだけ。
これで、optionキーがMetaキーとして動作します。

他の方法は?


方法としては幾らでもあって思いつくだけでもこんだけですね。

  1. Keyremap4macbookを使って変更する
  2. inputrcファイルを作成する

神保町でお安くOreiiy本(入門bash)をゲットしたので
ちょっと気になることとかやってるうちに小ネタが出ましたw

SSHで複数の鍵を管理する

SSHで鍵やユーザ名を複数のホストで使い分けないといけないときは結構面倒です。 ホスト毎の設定は「~/.ssh/config」で設定できます。

管理方法


以下の方法で管理します。

  • 鍵毎にprefixやsuffixをつける
  • sshのconfigにホスト毎に設定をつける

因みに、鍵がわかれば鍵ファイル名はなんでもいいです。

configの記載


以下のような形で記載します。

1
2
3
4
5
6
7
8
9
10
11
12
Host github.com
    HostName        github.com
    IdentityFile    ~/.ssh/github_id_rsa
    User            git
    TCPKeepAlive    yes
    IdentitiesOnly  yes
Host hogehoge
    HostName        hogehoge
    Port            12345
    IdentityFile    ~/.ssh/hogehoge_id_rsa
    User            hogehoge
    Protocol        2

各項目は以下の内容を設定しています。

設定項目 設定値
Host 次のHostキーワードが現れるまでの項目が1つの設定項目にする
HostName ログイン先のホスト名
IdentityFile SSHの鍵ファイル
User ログインするユーザー名
TCPKeepAlive 持続的接続
IdentitiesOnly IdentityFileを利用する場合に設定する
Port ポート番号
Protocol SSHのプロトコル指定

githubへのログインの場合は、上記の内容を記載します。

接続確認


以下のコマンドで確認します

1
$ssh -T <Host>

例えば、上記のconfigに設定したgithubへのアクセスは以下で確認します。

1
$ssh -T github.com

これで、「You’ve successfully authenticated」が出れば成功です。

以上で複数の鍵を管理できますね。

Macのディレクトリ名を英語化する

色々不便なのでやりました。
理由は、「ソートや補完とかが辛い」です。

英語化対象は、デフォルトで日本語化されているディレクトリです。
(「デスクトップ」という名前のディレクトリなど)

以下のコマンドを実行すれば、ディレクトリ名が英語化します。 やっていることは単純で、再帰的に権限維持したまま対訳表があるディレクトリをコピーです。

1
2
3
$ cd /System/Library/CoreServices/SystemFolderLocalizations/
$ sudo mv Japanese.lproj Japanese.lproj.bak
$ sudo cp -pr en.lproj Japanese.lproj

これで英語化されるね。。。

Linuxに接続したHDDを知る方法

バックアップ作業とかマウントとかで指定するんだけど・・・
どこだっけって探しまわるのも面倒なので、やり方をメモしておきます。

方法1:dmesgコマンドを使用


出力された結果をgrepします。

SATAの場合
1
$dmesg | grep sd
USB,PATAの場合
1
$dmesg |grep hd

方法2:dfコマンドを使用


自動マウントとかされている場合なんかだとこっちを使う

1
$df

結果を見れば、どのディスクがありどんなパーティションがあるか一目瞭然です。

方法3:/dev配下の内容+fdiskコマンドを使用


接続中のデバイスを知るには、lsコマンドで/dev配下を知ります。
以下の表のような感じになります。実際の割り当ては、OSやディストリに依存

パス 意味
/dev/hda IDEプライマリー(USB)のマスターディスク(hd以降は何が割り当てられるかはOS依存)
/dev/hda1 数字が付けば、パーティション
/dev/sda SATAもしくはSCSI
/dev/sda1 SATAもしくはSCSIのパーティション
/dev/md0 ソフトウェアRAID

接続中のデバイスがわかれば、以下のコマンドで詳細情報を得ます

1
$fdisk -l /dev/sda

方法4:/dev配下の内容+hdparmコマンドを使用


方法3と同じようにします。

1
$hdparm -i /dev/sda

fdiskがデバイスの情報に特化したものに対して、こっちは制御情報だったりステータスまで出てきます。

余談


単純にUSBで接続したディスクであれば、lsusbコマンドを使えばよかったりします。
ターゲットのディスクがわかれば、マウントも簡単になります。
マウントポイント(自分で決めて、作成する)を「/mnt/hdd」とした場合、以下のコマンドでマウント可能

1
$mount /dev/sda1 /mnt/hdd

自分は、方法1と方法3をよく使います。

DDコマンドで物理ディスクをバックアップする

どうも、どうも。久しぶりの更新です。
ゴタゴタが続いてたり、続いていなかったりでして。
更新するような感じのことができていません(勉強しろ)
まぁそんなどうでもいいことは置いておきまして、本題に入ります。

発端


最近、とある目的のためにWindowsPCを買いました。
中古で安く買ったのはいいのですが、ライセンス的なもので復旧用のディスクを頂けませんでした。
頂けない上にちょっとアレな感じなところもありまして・・・

とりあえず、以下でゴニョゴニョやってみました。

  1. Windows7に標準で搭載されているバックアップツール
  2. 出処不明のリカバリーディスク

結果として、どちらも失敗でした。
1はリカバーしたら古い情報も残ります。
残るだけならまだしも、色々ファイルも消えます。
2なんかは、インストールでドライバー用意しろと言われました。
なんか、ディスク起動もやたら遅いので怪しい感じ。。。

仕方ないので、ディスク換装した上に
元のドライブのデータを全て換装後のディスクにコピーして保存するようにしました。

バックアップ方法


ディスクのバックアップ方法ですが、「dd」コマンドを使用します。
このコマンドですが、「ハードディスク・パーティションを0/1の信号のママ丸ごとコピー」するものです。
注意点とすれば、以下のことでしょうか。

  • ハードディスクの容量がコピー元以上であること
  • コマンドで指定するディスクを間違えて指定した場合、データが消滅すること

バックアップ例


以下のような条件とします。

  • ディスクサイズは、「コピー先HDD ≧コピー元HDD」の大きさとすること
  • パーティションは、mountしないこと
  • コピー元HDDのパス、「/dev/sdb」
  • コピー先HDDのパス、/dev/sdc」

以下のコマンドで、上記のデータをコピーすることができます。

1
$dd if=/dev/sdb of=/dev/sdc bs=512 conv=noerror,sync

これで、コピーができます。 但し、完了までに数時間かかります。

さて、これでディスクからディスクにコピーすることができました。 それだけでなくバックアップ用のディスクイメージをつくることが出来ます

1
$dd if=/dev/sdb of=./backup-disk-image.img bs=512 conv=noerror,sync

故障ディスクのコピー


上記のコマンドを使えば、故障している(ある程度読める必要がありますが)ものまでコピーできます。
まぁ強引に読んでる(読めないところは、スキップしています)だけです。

上記のコマンドに設定しているオプションは、以下の表の意味です。

オプション 内容
noerror エラー読み飛ばし
sync エラー箇所をNUL(ゼロ)で埋める
bs byte size 読込書き出すバイトサイズ

因みに、byte size値が大きいとコピー速度が速くなります。
但し、壊れている部分があると道連れになる部分が大きくなります。
なので、byte size値を小さくするとエラー範囲は最小になります(コピー速度が遅くなります)

転送状況の表示


ddコマンドには、転送状況を表示してくれるようなオプションはありません。
以下のように、killallコマンドのUSRオプションで途中経過を表示できます。

1
$killall -USR1 dd 

これで、どれくらいかかるか時間計算ができますね。

ディスクイメージからの復元方法


ディスクイメージのバックアップは取れましたが、ディスクイメージからの復元が必要ですね。
といっても、ここまでで大まかに理解できそうな感じがしますが・・・

1
$dd if=./backup-disk-image.img of=/dev/sdb bs=512 conv=noerror,sync

コピー元とコピー先を入れ替えるだけですね。

ディスクの消去


復元と同じ要領で、zero埋めすれば完全フォーマットができます。

1
$dd if=/dev/zero of=/dev/sdc

このコマンド本当に便利。
LinuxとかMacのディスクだけでなくって、Windowsなディスクまで丸ごとコピーできるところが素敵。
ファイル指定はできないけどw

Rubyでアクセス用のメソッドを定義する(アクセッサ)

なんてことはない、ただの整理です。

通常インスタンス変数を外部から参照する方法は、インスタンス変数を操作するgetter/setterメソッドを作ります。

Rubyでは、このアクセス用のメソッド(アクセッサ)を簡単に作る機能があります。

以下のようなModuleクラスにあるものを使います

  • attr_reader : 参照(読み出し)できるようにする(getter)
  • attr_writer : 代入(書き込み)できるようにする(setter)
  • attr_accessor : 参照、代入の両方できるようにする(getter/setter)

それぞれ、使い方は以下のような形になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Accessor

    attr_reader :name,:hoge
    attr_writer :fuga,:piyo
    attr_accessor :access
    
    def initialize
        @name = "kurobara"
        @hoge = "hogehoge"
        @fuga = "fugafuga"
        @piyo = "piypiyo"
        @access = "OK"
    end

    def print_fuga_piyo
        p '---------------------'
        puts "fuga = " + @fuga
        puts "piyo = " + @piyo
    end

end

a = Accessor.new()
puts a.name
puts a.hoge  
a.print_fuga_piyo
p "代入操作"
a.fuga = "fuga2fuga2"
a.piyo = "piyo2piyo2"
a.print_fuga_piyo
p '---------------------'
puts 'a.access = ' + a.access
p "代入操作"
a.access = "OKOK"
puts 'a.access = ' + a.access

こんな感じで使えちゃいます。。。
今更初心者みたいなことしてんなって突っ込まれそうだけど・・・
attr_accessorばっかり使うので、attr_reader,att_writerを忘れてましたw

RubyでSingletonパターンを実装する

このまえ、友人とデザインパターンの話をしてたような気がするので書いてみた。

SingletonはGOFのデザインパターンの一つです。
使い所は、システム内で絶対に一つにしておかないといけないもの仕組みのものに使います。
例えば、アプリの設定とか見た目(Look&Feel)とかシステムの何かを管理するだとかに使ったりします。

Singletonは以下の条件を満たす必要があります。

  • 作成したクラスのインスタンスは一つだけであることが保証されている
  • コード上のどこからでも、生成した1つだけのインスタンスにアクセスできる

Javaで上の条件を満たすものはこんな感じ

1
2
3
4
5
6
7
8
9
10
11
final class Singleton {
    private static Singleton instance;
    private Singleton(){};

    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

これと同じ実装をRubyでやるとこんな感じになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Singleton
  @@singleton_obj = nil
  @@count = 0

  # 以下の行をコメントアウトすると
  # オブジェクトが再生成されるので
  # シングルトンにならない
  private_class_method:new

  def initialize
    @@count = 1
  end
  
  def self.get_instance
    if @@singleton_obj == nil
      @@singleton_obj = new
    end
    @@singleton_obj
  end

  def self.count_up
    @@count+=1
  end

  def self.print_count
    p @@count
  end
  
end

p '-----------------------'
p '初回インスタンス取得'
p Singleton.get_instance
Singleton.print_count
p '-----------------------'
p '2回目のインスタンス取得でオブジェクトに変更がない'
p Singleton.get_instance
Singleton.count_up
Singleton.print_count
p '-----------------------'
p 'newするとエラーが飛ぶ'
begin
  Singleton.new
rescue
  p 'newでエラーが飛んだ'
end

結構長いですねw

上記のコードの実行結果は、以下になります。
オブジェクトに変化が無いことがわかりますね。
つまり、オブジェクトが1つであることが、保証されています。

1
2
3
4
5
6
7
8
9
10
11
"-----------------------"
"初回インスタンス取得"
#<Singleton:0x007f91519026f0>
1
"-----------------------"
"2回目のインスタンス取得でオブジェクトに変更がない"
#<Singleton:0x007f91519026f0>
2
"-----------------------"
"newするとエラーが飛ぶ"
"newでエラーが飛んだ"

自力でSingletonを実装すると上記のようなコードなのですが、
実は、Rubyにはsingletonをやってくれる便利なモジュールがあります。
これを使うと、Mix-inしたクラスのインスタンスは常に同じものを返してくれます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
require 'singleton'

class MySingleton

  include Singleton

  @@count = 0

  def initialize
    @@count = 1
  end

  def self.count_up
    @@count+=1
  end

  def self.print_count
    p @@count
  end
end

p '-----------------------'
p '初回インスタンス取得'
p MySingleton.instance
MySingleton.print_count
p '-----------------------'
p '2回目のインスタンス取得でオブジェクトに変更がない'
p MySingleton.instance
MySingleton.count_up
MySingleton.print_count
p '-----------------------'
p 'newするとエラーが飛ぶ'
begin
  MySingleton.new
rescue
  p 'newでエラーが飛んだ'
end

実行結果は、こんな感じ

1
2
3
4
5
6
7
8
9
10
11
"-----------------------"
"初回インスタンス取得"
#<MySingleton:0x007fd2fa8c9658>
1
"-----------------------"
"2回目のインスタンス取得でオブジェクトに変更がない"
#<MySingleton:0x007fd2fa8c9658>
2
"-----------------------"
"newするとエラーが飛ぶ"
"newでエラーが飛んだ"

モジュールを使うと、スッキリとしたコードになりますね。
当たり前ですが、newしようとするとエラーになります。

MacにGUIありWiresharkをインストールする

いつも忘れるのでいい加減にメモを残しておきます。

インストール環境


以下がインストールされているマシンであること

  • XQuartz
  • Homebrew

XCodeが古かったりするとインストールできない可能性があります。
少なくともwarningは出ます。

インストール方法


以下のコマンドを実施することでGUIありWiresharkがインストールできます。

1
$brew install wireshark --with-x

因みに「–with-x」オプションがない状態でインストールするとGUI無しのwiresharkがインストールされます。

Wireshark起動方法


以下のコマンドで起動します。

1
$sudo wireshark

毎回実施しては、毎回思うのだけど・・・ Homebrew使わずにインストールしたほうが手っ取り早いような気がする。。。

端末にインストールしてあるapkファイルを取り出す

訳があって実施することになりました。
ビルドに使ったソースコードがなくなってしまっただけなんですけどね。

前提


  1. adbコマンドが使える環境であること
  2. 端末がデバッグモードONであること

手順


以下の方法で実施します。

  1. adb shell pm list packages -f | grep [取得対象のパッケージ名の一部]
  2. 1を実行すると「package:/data/app/<apkファイル名>=<アクティビティ名>」が表示される
  3. adb pullコマンドでapkファイルのフルパス(/data/app/<apkファイル名>)を指定する

これだけです。

一応ソースコードを紛失したapkのバイナリが取り出せました。
別の端末にインストールできる。
よかったよかった。