Bonkura - Kenny

SIerで働く文系SEの記録

『人月の神話』王道はない。しかし、道はある。

人月の神話

人月の神話

古典や名著と呼ばれる本には、年月が過ぎても決して色褪せない魅力があるらしい。そうでなければ長い年月の間で徐々に読まれなくなり、忘れられてしまうから。
ITという100年ちょっとしか歴史が無い分野においても、そんな本は存在しているみたいだ。『人月の神話』はインターネットが当たり前のインフラになって久しい2017年においても、たくさんのエンジニアに絶賛されており、「エンジニアが読むべき◯冊」的なエントリには高い確立でノミネートされている気がする。
エンジニアの端くれとして読んでおかないとなぁ、、と思い実際に読んでみると、古くから読まれ続ける古典であり、名著である理由がわかった。日本のIT業界に務めるエンジニアが「あーあるある」と共感するための本なのだ。(それがいいのか悪いのかはおいておいて)

人月

  • 人月は、間違った危険な神話である。というのも、人月とは「人」と「月」が相互に交換可能だということを意味しているからだ。
  • 多くの作業者の間でコミュニケーション(意思疎通)を図らなくても、仕事が分担出来る場合だけである。
  • ブルックスの法則ー遅れているソフトウェアプロジェクトへの要因追加は、更にプロジェクトを遅らせるだけである。

MMとかMDという単位で見積もられる工数は、小規模なプロジェクトであれば大きなズレはないかもしれないけれど、プロジェクトの人数が増えれば増えるほど、コミュニケーションコストが増大する。もしその状態でプロジェクトスケジュールが遅れたとして、そこに新たに人をアサインしたとしても、教育コストやコミュニケーションコストによって、既に遅れているプロジェクトが更に遅れるという炎上待ったなしの展開に陥る。
チームで働く仕事において、コミュニケーションコストというのは本当に馬鹿にならない。チャットを使おうかメールを使おうが電話を使おうが、根本から問題を解決出来る銀の弾丸なんてもちろん存在しない。コミュニケーションに王道は存在しない。「メールじゃなくて、とにかく電話しろ」という単純な考えは間違っている。

チーム構成

  • 少数精鋭チームが最高である
  • 但し、大規模システムに対して時間がかかりすぎる
  • 外科手術チームのような編成であるべき

外科手術チームという概念を借りて話すと、メインの執刀医に選ばれなかった医者の悔しさがプラスに働くのかマイナスに働くのか、考慮する必要のある問題だと思う。つまり、プログラミングがしたいのに文書管理しかやらせてもらえないギークのモチベーションはどうなってしまうのか、ということ。少数精鋭チームが最高であるのは間違いないが、モチベーションの維持管理はまた別の話である。

コンセプトの完全性

  • コンセプトの完全性こそ、システムデザインにおいて最も重要な考慮点
  • デザインは1人または互いに意見が同じで共鳴しているごく少数の頭脳から考え出されなければならない

業務システムやWebサービスの根底にあるシステムデザインや設計思想に反する機能を顧客の意のままに追加していくと、コンセプトの完全性が保たれたシステムからどんどん離れていく(実体験
コンセプトの完全性を守るのは難しい。が、守る事が出来るのは、コンセプトの完全性を理解している人だけなのだ。(僕はだめでした

組織・文書

  • 組織の目的は、必要となるコミュニケーションと調整作業の量を減らすこと
  • 組織は、コミュニケーションを不要にする為の作業の分担と機能の専門家を具体化したもの
  • マニュアルとは、製品の外部仕様書である
  • やがて少しづつこうした文書の中にある小さな集まりが、自分の管理という仕事の多くを具体的に表現しているのだと言うことが分かってくる。その1つ1つを綿密に準備することによって、考えを集中させたり、収拾がつかなくなりそうな議論をまとめる際、役立てたりすることができる。そして、それをたえずきちんと整理しておけば、監視及び警告の仕組みとなる。

組織と文書。実際の所、SIerに勤めている自分の仕事の内容はコミュニケーションと文書作成ばかりで、高いモチベーションで取り組めているとは言い難い。ただ、それがの仕事が重要であるということも理解しているつもり。
読んだ本の中に「その通り、重要なのだから、ちゃんとやれ」と書いてあったとしても、素直に受け止めて「よし!頑張ろう!」となるような素直さは持ち合わせてはいないのだけれど。

我々の作業にまつわる主要な問題は、本質的には技術的というより社会学的なものだ

ソフトウェア開発の性質

  • 複雑性
  • 同調性
  • 可変性
  • 不可視性

ソフトウェアは複雑で、同調圧力に晒され、可変性を要求され、不可視性を持つ。なんてやっかいなシロモノだ。それが面白い。

王道はない。しかし、道はある。

USB温度センサーで部屋の温度を可視化してみた。(RaspberryPi+Fluentd+Elasticsearch+Kibana4)

「Fluentd使って何か作りてぇなぁ…」と思っていた所、amazonでお安く売っているUSB温度センサーがあったので、部屋の温度を可視化してみました。色々と躓いて一週間くらいかかってしまったのですが、なんとか構築する事が出来たので、紹介します。(やりつくされたテーマな気もしますが、ご愛嬌。)

構築に使った物たち

サーバ

  • Raspberry Pi2 Model B
  • (上記とは別に)CentOS6.7の入ったサーバ(ESXi上で動いている仮想マシン

ミドルウェア

  • Fluentd
  • elasticsearch-2.3.3
  • kibana-4.5.1-linux-x64

温度センサー

  • USB温度計! USB thermometer-528018

USB温度計! USB thermometer-528018

USB温度計! USB thermometer-528018

概要

システム構成図は以下の通りです。ラズパイ側でログを収集して、CentOS側でログ保存と可視化用のミドルウェアであるKibanaを動かしています。

f:id:knygt15437:20160627171032p:plain

実際の画面

こんな感じになります。クーラーを入れたタイミングで温度が急激に下がってますね。あと、常に2時間タイマーでセットしているからなのか、2時間くらいたったら徐々に温度があがっているようです。

f:id:knygt15437:20160627171035j:plain

次からは手順メモを忘れない!

色々と苦戦しすぎて手順のメモを忘れてしまっていたので、詳しい構築手順までは残ってないのがホント駄目だなぁ、、と自分でも思います。なので、今回はとりあえずこんなん作ったよーというご紹介に留めておきます。。

【たのしいRuby_21】Procクラス

たのしいRubyの第21章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

ブロックとして記述された手続きを持ち運ぶためのクラス。

Procクラスとは

  • Proc.newメソッドにブロックを与えると、そのブロックを保持するProcオブジェクトが作られる。
  • ブロックはProc#callメソッドによって実行される。
  • Proc#callメソッドを呼び出した時の引数がブロック変数となる。
  • ブロックで最後に評価された値がProc#callの戻り値となる。
  • ブロック変数を「|*配列|」の形式にすると、不定の引数を配列で受け取る事が出来る。
#うるう年判別処理

leap = Proc.new do |year|
  year % 4 == 0 && year % 100 != 0 || year % 400 == 0
end

p leap.call(2000)
p leap.call(2013)

#要素を二倍にして返す処理

double = Proc.new do |*args|
  args.map{|i| i * 2 }
end

p double.call(1,2,3)

lamda

Proc.newの別の書き方。違いとしては、下記の2つがある。

  • 引数のチェックが厳密になる
  • ブロックから値を返すときにreturnを使える

【たのしいRuby_20】Timeクラス、Dateクラス

たのしいRubyの第20章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

TimeクラスとDateクラス

  • Timeクラス: 「年月日日時分秒」タイムゾーン の情報を持つ
  • Dateクラス: 「年月日」 だけを扱う。

Timeクラス

# 現在時刻の取得

p Time.new
sleep 1
p Time.now

#=> 2016-05-29 16:57:05 +0900
#=> 2016-05-29 16:57:06 +0900

t = Time.now

p t.year #=> 2016
p t.month #=> 5
p t.day #=> 29

#指定した時刻を表すTimeオブジェクトを得る

t2 = Time.mktime(2016,5,30,1,1,1)
p t2 #=>2016-05-30 01:01:01 +0900

# 時刻計算(秒数基準)
t3 = t2 + 60 * 60 * 24
p t3

# 時刻フォーマット修正(文字列型への変換)
t4 = Time.now
p t4.to_s
p t4.strftime("%Y-%m-%d")

Dataクラス

時刻を持たない日付を操作するためのクラス。

require "date"

d = Date.today

p d.year
p d.month
p d.day

# 月末の日付を-1で指定出来る。閏年にも対応している!
d = Date.new(2016,2,-1)
puts d  #=> 2016-02-29

【たのしいRuby_19】Encodingクラス

たのしいRubyの第19章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

プログラムがどのように文字コードを扱うか、言語によって異なる。Rubyは、、、

という2つの情報を持っている。文字コードに関する情報を エンコーディング と呼ぶ。

文字列オブジェクトを作るには、大きく分けて二通りの方法が存在する。

  • スクリプトリテラルとして記述する方法
  • プログラムの外部(ファイル・コンソール・ネットワークなど)から情報を受け取る方法

Rubyエンコーディングで使う情報

リテラルに記述した文字列オブジェクトのエンコーディングを決定する情報。 スクリプトそのものの文字コードと一致 する。

外部から受け取ったデータをプログラム内でどのように扱うか?という情報

プログラムを外部に出力する際のエンコーディングに関する情報。

スクリプトエンコーディング

スクリプト自体のエンコーディングのこと。スクリプトエンコーディングEUC-JPなら、文字列のエンコーディングEUC-JPになる。スクリプトエンコーディングを指定するために使われるのが、 マジックコメント である。

# encodign: utf-8

hoge

Encodingクラス

文字列のエンコーディングを調べるには、String#encodingメソッドを使う。

p "こんにちは".encoding #=> #<Encoding:UTF-8>

str = "こんにちは".encode("EUC-JP")
p str.encoding #=> <Encoding :EUC-JP>
str2 = "こんにちは"

# 文字コードが違うため、false
p str == str2

その他メソッド

# 2つの文字列の互換性をチェックする。
p Encoding.compatible?("AB".encode("EUC-JP"),"".encode("UTF-8")) #=> #<Encoding:UTF-8>
p Encoding.compatible?("".encode("EUC-JP"),"".encode("UTF-8")) #=> nil

# デフォルトの外部・内部エンコーディングを返す
p Encoding.default_external
p Encoding.default_internal

# Rubyがサポートしているエンコーディングの一覧を返す
p Encoding.list

IOクラスとエンコーディング

外部エンコーディング・内部エンコーディングを明示的に設定しない場合は、デフォルト値となる。デフォルト値の確認はdefault_external,default_internalメソッドで確認できる。

IOオブジェクトのエンコーディング(ファイルをどのように扱うか?)という設定。

File.open(file,"mode:encoding:encoding")
# 第一引数に外部エンコーディング、第二引数に内部エンコーディング
# 例 File.open("hoge.txt", "r:Shift_JIS:UTF-8")

出力時エンコーディングの動き

入力時エンコーディングの動き