ラベル システム開発 の投稿を表示しています。 すべての投稿を表示
ラベル システム開発 の投稿を表示しています。 すべての投稿を表示

2017年8月31日木曜日

米国IT求人の片隅を覗いてみる...

この投稿、本当はQiitaに出したかったのですがなぜかQiita側が受け付けてくれないのでやむを得ず本ブログに保存しておきます。


先日とあるところで「アメリカにおけるAgile開発ってどれくらい浸透しているの? ペアプログラミングとか本当にやってるの? 一人で設計から開発からテストまでこなすって本当?」等などの質問を受けたのでちょっと調べてみました。



これはバンクオブアメリカの求人広告で、勤務先はニュージャージー州。Pegaを使ったワークフロー処理関係の開発と思われますが

  • ユーザーと共に要求定義の見直しを行い
  • スケールする高品質のシステムの設計と開発を行い
  • 品質保証や受け入れテストにおいてユーザの支援を行い
  • 5年以上の.NETもしくは他のオブジェクト指向言語の開発経験があり
  • Pega Roboticsでのワークフロー自動化開発経験があり
  • マイクロソフトOfficeのオートメーション開発の経験があり
  • オブジェクト指向設計パターンのしっかりした知識があり
  • 再利用性、テストのしやすさ、スケールしやすさ、保守のしやすさなどを考慮したアーキテクチャを実現できる能力があり
  • モデリングツールを使いこなせて
  • TDD/BDD、リファクタリング、テスト自動化フレームワーク、継続的統合、継続的デリバリの経験があり
  • Gitなどを使ったリリースマネージメントの経験があり
  • ペアプロや日々のスタンドアップミーティングなど、Agile開発に明るく
  • これまで働いてきた分野での問題領域に関する知識を持っていて
  • できれば...
  • Functional Programmingの経験があり
  • 分散システム開発の経験があり
  • Angularなどを使ったWebフレームワークでの開発経験や、RESTfulサーバの開発経験があり
  • 銀行系システムの経験があることが望ましい


こういう技術者をバンカメクラスの金融機関が直接雇用してバリバリ開発を進めてしまう、というのが米国のIT現場の姿の一端でしょうね。SI業者へのアウトソースも存在しますが、開発速度や柔軟性が求められる分野は圧倒的に内製なんですね。

ちなみに気になる給料ですがこれはGlassdoorから参考値を探せます。

 おそらく初年度は10万ドルくらいではないかと。間接コストを含めるとバンカメ側の予算はこの二倍かそれ以上かかっているのではないかと思われますが、それでも総合的に見れば「安い」からバンカメはアウトソースしないのでしょう。

1999年公開の映画「Office Space」では米国にもシステムインテグレータ的な会社が残っていました。要求定義する人と開発する人とテストする人は別だった時代。

あれから15年ちょっと経過。


アメリカのIT産業は様変わりしたと言って良いでしょう。

2011年11月15日火曜日

ウォーターフォール脳に冒された日経SYSTEMS池上俊也記者はAgileとCloudの隆盛に自己存在意義の危機という悪夢を見たのか?(仮題

お断り: 題名はTweetしにくいように意図的に長くしてあります。

日経ITPro: 「規模見積もり」が消えてしまう?
→クラウドやAgileを活用した「作りながら煮詰めていく」開発の普及で「規模見積もり」という習慣がなくなり

  • プロジェクトがコントロール不能に陥る
  • 準委任契約が広がる可能性がある

ということを日経SYSTEMS池上俊也記者は懸念している。ちなみに過去にもこの人にケチつけたことあり。

そこで本記事では

  • 果たしてそんなことはあるのか? あったとして問題なのか?
  • そもそも規模の見積もりにどれほどの価値があるのか?
を中心に突っ込んでみる。

突っ込み(1) 「規模見積もり」がなくなるとプロジェクトはコントロール不能に陥るか?

規模見積もりの結果である成果物スコープは、工数の算出につながり、それが期間やコストの見積もりのインプットとなる。つまり成果物スコープがないと、プロジェクトの計画値のほぼすべてが根拠の乏しいものになってしまう。計画値がブレれば、プロジェクトのコントロールは困難を極める。
これは「ブレない計画を策定することは可能である」という前提で話をしているよね。IT業界の先人・諸先輩あるいはA級戦犯の皆様方はこの「ブレない計画・ブレない見積り」というピンクのドラゴンのようなものを求めて散々苦労し、数々のデスマーチプロジェクトを生み出してきたわけだ。

見積もりは必ずブレる。なぜなら見積もりは確率分布だからだ。その事実を理解せず、「ブレない見積もり・ブレない計画」の存在を前提としてプロジェクトを進めるから制御不能=デスマーチに陥る確率が高くなるわけでしょ。

むしろ「見積もりはブレる」という前提でプロジェクトを組み立てるAgileのほうが、より現実的な対応が可能になるわけで。ただしこれは「Agileがプロジェクトの成功を約束する」というわけではない。計画が現実離れしていれば、プロジェクトの早い段階でAgileチームは降参するしかない。だがそれは引くに引けないプロジェクト最終段階で刹那的に戦力を追加投入せざるを得ないウォーターフォールのデスマーチよりは余程「よく制御されている」と言えるのではないか。

突っ込み(2) 「規模見積もり」がなくなると準委任契約が広がるのか? 

もう一つの問題は、規模見積もりが実質的に消えることで、準委任契約が広がる可能性があることだ。以前はプロジェクトの上流工程のみに準委任契約が適用され、後工程は請負契約となることが多かった。それが最近は“作っては見直す”というアジャイル開発において、全工程を準委任契約で進めるケースが少なくないようだ。
 準委任契約は、ユーザー企業にプロジェクトのリスクが付くことを意味する。極端に言えば、ベンダーがユーザーに対して「作ってみなければいくらかかるか分からない」と突き付けているようなものだ。ベンダーにとっては事前に規模見積もりをしないだけに、何を作るのかが不透明で、準委任契約をせざるを得ない事情がある。かかった分へのコストが保障される契約なので、ベンダー側が生産性向上施策を積極的に取りづらく、業界発展の妨げにもなりかねない。
準委任契約が増える可能性は否定できない。だが、後半の「かかった分へのコストが保障される契約なので、ベンダー側が生産性向上施策を積極的に取りづらく、業界発展の妨げにもなりかねない」というのは誤りだろう。

Agile的に開発していくからには、例えば一ヶ月とか三週間ごとに成果物を納品していくことになる。その出来具合と契約に基づく価格とを比較して「それはないんじゃない?」と発注側が感じたら、受託側に相談すればいいだけのこと。ウォーターフォールで「こんなはずじゃなかった」と文句を言えるのは早くて数ヶ月、ひどければ一年も二年も待った後なのである。「ベンダー側が生産性向上施策を積極的にとりづらい」のはどちらの手法だろうか?

またウォーターフォールの場合、規模見積もりにゲタを履かせて「かかった分のコストを保障させる」という契約がまかり通ってしまってきたわけだ。これこそSI屋やベンダへの信頼を失わせ業界発展の妨げとなってきた感があるのだが日経SYSTEMSはそのあたりをどう考えているのだろう?


突っ込み(3) そもそも規模の見積もりにどれほどの価値があるのか?
引用記事ではFP法などが紹介されていたけどさ。FP法って自分が社会人になった80年代にはすでに存在していたと記憶しているけど、未だに普及しているとは言い難いよね。自分もかじったことがあるけど、結局は測定者の主観と匙加減でどうにでもなる指標でしかないし、「ブレがない」とは言い難い代物である。しかもわかりにくい。SI屋による人月コスト保障の隠れ蓑にFP法見積もりが悪用されたとしても、お客さんが指摘することは無理でしょ。

仮にFP法が「客観的」で「誰がやっても同じ規模の見積もり」を導出できるとして、それが何になるというのだろう?「このプログラムはFP法で3000ポイントの規模となります」という数字が出た所で、それを「いくらで」「どれくらいの期間で」開発できるのかはまた別の話なわけで。まさか「プログラマAは月間300FPの開発ができる」とか測定するわけにもいくまいし。「秋季情報処理試験・FP能力測定試験」なんて嫌だよね?

そして「規模見積もり」にこだわる人達に決定的に欠けているのは「不具合対応にかかる期間と費用」の概念なんだよね。これから書くソースコードにどれくらいバグが含まれていて、テストでどれくらいの確率で捕捉されて、それらがどれくらいの期間で修正されるのか、なんてのを計画段階で決定できるはずがないのだよ。そこを決定論的に予め計画に組み込もうとするからプロジェクトが制御不能に陥りやすくなるのだけど、ウォーターフォール脳には理解出来ないものなのか。

このエントリーをはてなブックマークに追加

2011年8月24日水曜日

NoSQL DB vs RDB

ということでNoSQL Now二日目に参加中。基調講演を聞き終えたところ。以下、メモ。

  • NoSQLは従来型RDBの抱える制約を打破するために生まれたのかね?
  • その「制約」も色々あって、どこに問題の本質を見るかで答えは変わってくるよね?
  • 性能?
    • 書き込み
      • 単発
      • 関連する複数レコード
    • 読み出し
      • 単発
      • Joinを伴う読み出し
  • 保守性?
    • カラムを足す、ということだけでも面倒。
    • リレーションが絡むとさらに厄介。
    • テーブル仕様記述だけでなく、オブジェクト側やORマッパーについても仕様記述同期が必要。
  • どの問題を片付けるか優先度をつけないと、問題の解決手段も見つからない。少なくとも現在の技術では(たぶん未来永劫)上記問題を「すべて同時に」解決することはできない。

2011年7月27日水曜日

オフショア開発ってなんだったの?(勝手に総括)

今日印象に残った話→「オフショア開発って一体なんだったんだ?」

インドだ中国だベトナムだフィリピンだロシアだ東欧だ等々と言われたけど、詰まるところは「円高差益」でしかなかったのでは、という指摘。つまり、日本円が独歩高になるにつれて相対的に安くなる海外の労働力を「日本は高付加価値の仕事」「通貨の安い国に低付加価値の仕事」という基準で活用していただけではないかと。

で、どこかの時点でそれがいつかはわからないが円安に転じる時に、「通貨の高い国に低付加価値の仕事を出さざるを得なくなって日本の情報産業は競争力マイナスになるよね」という予測。

アメリカでAgile内製やってた人達は、自国通貨がどこかで安くなるという予測をしていたのかどうかは知らないけど、「コア開発は米国でAgile的に内製」という事業構造に転換していた人達は、結果的に自国通貨安で大きな恩恵を受けているのは事実なわけで。

というわけで勝手にオフショア開発を総括すると

オフショアの労働力が安い間はそこに古い技術で外注を出すけど、それで時間を稼いでいる間に自国内で立ち上げるべき高付加価値な事業をできるだけ内製で作れるように体質を改善する

というのが正解だったのかな、と。そうじゃなくてオフショア開発依存症になってしまった人達はよっぽど頑張って体質改善しない限りある日突然通貨安という死刑宣告がやってくるんだね。

ということで総括終了。

2011年5月28日土曜日

バグ放置が犯罪とな? 由々しき問題である

高木さんの日記にて、ウイルス罪法案、バグ放置が提供罪に該当する事態は「ある」と法務省見解という記事が公開されている。一部引用:
情報技術に疎い方々からすれば、プログラムといえばワープロのような、商用のソフトウェアばかりだと思えるのかもしれないが、そうではない。フリーソフトウェアのように、「as is」で、すべて利用者の責任で使うことを条件に、自由なソフトウェア開発と自由な流通を促進することによって、これまでソフトウェアが発展してきた歴史的経緯がある。法務省はそのことを理解しているのか、この答弁のままでは、疑われるのではないか。
僭越ながら補足を...

現実は フリーソフトウェアがソフトウェア産業を支えている、と言っても良い。人間が書いたソースコードをコンピュータが理解できる形式に翻訳するコンパイラはフリーソフトウェアであることが多いし、みんながこうして読んでいるWeb画面を生成しているサーバの多くもフリーソフトウェアで支えられていることがほとんどだと思って良い。

試しにGNU Compilierが利用許諾契約として採用しているGPLの一部を抜粋すると

15. Disclaimer of Warranty.THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
Webサーバによく使われているApacheサーバのライセンスには
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any 
と、「as is」がでてくる。「あるがまま」という意味である。つまり、これらフリーソフトウェアは「出荷状態において品質や性能で問題が含まれる可能性もあるが、使用する側の責任でなんとかしてね。(ソースは開示されているんだからさ)」という条件に合意しないと使うことができない。


「問題があるかもしれないがお前の責任だ」などという条件の元では恐ろしくて使えない、と考えるのであればあなたは高木さんが叩いている議員さんやお役人と似た様な思考回路を持っている可能性がある。そもそもあるプログラムコード一式の中に「バグがない」と保証するのは並大抵の労力ではできないのである。「検査もプログラムでやったら?」と思う人がいるかも知れない。でも、その検査プログラムにバグがないと誰が保証するのであろうか。つまるところ、ソフトウェアなんてのは人がプログラムコードを書いて、それをテストするコードも人が書くしかない。


すなわち、ソフトウェアとは人間の作業の集大成なのであり、人間が完璧でない以上、プログラムコードのどこかにバグが入り込むことを完全に排除することなど無理なのである。検査を徹底することで相当な部分を検知し、対処することは可能かもしれないが、そのための作業時間・費用は膨大なものになろう。(それでも「バグがない」と保証するのは不可能かもしれない。) 結果、できあがるソフトウェアは高価なものとなり、私達の暮らす世界は今とは異なる姿となるかもしれない。パソコンやiPhoneが数百万円するとか、電子制御装置を搭載したカローラが何億円もするとか、Webサーバを設置できる企業は世界に数社しかいなくて、それを閲覧するのは金持ちの道楽になるとか。


フリーソフトウェアは「as is」という条件を利用者に強いることで、出荷までの敷居を限り無く低くすることができた。より多くの人が利用し、利用する上で見つかる問題点が開発者達にフィードバックされることで、ソフトウェアの品質や性能が向上してきた。出荷の敷居を下げることでソフトウェア価格は下がり、低価格路線を維持できた。結果として、より多くの人達がソフトウェアの恩恵を受け取れた。このような背景でコンパイラやWebサーバ等が育ってきたからこそ、我々は様々なソフトウェアやサービスを安く(あるいは無料で)利用することができるようになったのである。


その過去を一切否定するような「バグ放置は犯罪」などと主張する政治家には去ってもらいたいし、「バグ放置を犯罪」とするような立法の動きには強く警戒する必要がある。


注: ここでいうフリーソフトウェアとはFSFの言ってるフリーソフトウェアのこと。

2011年5月5日木曜日

It's a Sony!

こちらから頂いてきた。

#!/usr/local/bin/perl


eval {

   #########################################################
   # Read in the string from the form
   #########################################################

   if ($ENV{'REQUEST_METHOD'} eq "GET") {
           $FORM_DATA = $ENV{'QUERY_STRING'};
   } else {
      $LENGTH = $ENV{'CONTENT_LENGTH'};
      while ($LENGTH) {
         $FORM_DATA .= getc(STDIN);
         $LENGTH--;
      }
   }

   #########################################################
   # Split the input string into individual variables
   #########################################################


   foreach (split(/&/, $FORM_DATA)) {
      ($NAME, $VALUE) = split(/=/, $_);
      $NAME =~ s/\+/ /g;
      $NAME =~ s/%([0-9|A-F]{2})/pack(C,hex($1))/eg;
      $VALUE =~ s/\+/ /g;
      $VALUE =~ s/%([0-9|A-F]{2})/pack(C,hex($1))/eg;
      # find a unique name for select boxes
      $NUM ="0";
      while ($FORMDATA{$NAME} ne "") {
         $NUM++;
         $NAME =~ s/\.([0-9]+$)|$/\.$NUM/;
      }
      $FORMDATA{$NAME} = $VALUE;
   }

   $product = $FORMDATA{"product"};
   $product =~ tr/a-z/A-Z/;
   
   $docdirname = "/ws/w1/htmldocs/shared/semi/PDF/";
   $docext = "pdf";
   $docurlbase = "/semi/PDF/";
   
   $filename = "$docdirname$product.$docext";
   $default = "$product.$docext";
   
   local(@matched, @ids, $re);
   # get a list of the product ids
   opendir(DOCDIR, $docdirname) || die($ENV{'SCRIPT_NAME'}||$0. ": opendir(): can't open directory \"$docdirname\": $!\n");
   @ids = readdir(DOCDIR);
   closedir(DOCDIR);
   @ids = grep(/\.$docext$/i && s/\.$docext$//i, @ids);

   if(@matched == 0) {
      # make a regexp of possible $product matches
      $re = $product;

      # look for match
      @matched = grep(/$re/i, @ids);
   }
   if(@matched == 0) {
      # make a regexp of possible $product matches
      $re = join("|", omit_list(+1, $product), 
                      omit_list(-1, $product), 
                      miss_list(-1, $product), 
                      transpose_list($product));
      $re = '^(?:'.$re.')$';

      # look for match
      @matched = grep(/$re/i, @ids);
   }

   # sort @matched
   sub sortsub {
      my $ta, $tb; 
      ($ta = $a) =~ tr/A-Z/a-z/;
      ($tb = $b) =~ tr/A-Z/a-z/;
      $ta cmp $tb;
   }
   @matched = sort sortsub @matched;
   
#   if((! -r $filename) && (@matched != 1))) { 
   if(@matched == 1) {
      $errmsg = "

The product code you entered, $product, is similar to this product: ". join("", map("$_", @matched)). ". If this is not what you wanted, you can try another product code, or go to a product category, by selecting it below."; } elsif(@matched > 1) { $errmsg = "

The product code you entered, $product, is similar to these products:

    ". join("", map("
  • $_", @matched)).
    "

If none of these are what you wanted, you can try another product code, or go to a product category, by selecting it below."; } else { $errmsg = "

Sorry, the product code you entered does not exist. Please try another product code, or go to a product category by selecting it below.

"; } }; ### ### $error_file = "/ws/w1/htmldocs/shared/semi/searcherror.html"; $errmsg_spot_re = ""; if($errmsg || $@) { $errmsg = $errmsg || "the script encountered a serious problem and couldn't complete your request: $@"; print("Content-type: text/html\n\n"); open(ERROR, $error_file); $e = join("", ()); close(ERROR); if($e ne '') { $e =~ s/$errmsg_spot_re/$errmsg/g; } else { $e = "Serious error: $!, and $errmsg"; } $e .= "\n"; print($e); } # package alink::oneoff; sub uniq { my %H = (); grep(!$H{$_}++, @_); } sub nonuniq { my %H = (); grep($H{$_}++ == 1, @_); } sub omit_list { my $e_len = shift; my @R = (); my $g; foreach $g (@_) { my $g_len = length($g); if($e_len > 0) { push(@R, uniq(omit_list($e_len-1, map(substr($g,0,$_).".".substr($g,$_), (0..$g_len))))); } elsif($e_len < 0) { push(@R, uniq(omit_list($e_len+1, map(substr($g,0,$_).substr($g,$_+1), (0..$g_len-1))))); } else { push(@R, $g); } } @R; } sub miss_list { my $e_len = shift; my @R = (); my $g; foreach $g (@_) { my $g_len = length($g); if($e_len < 0) { push(@R, uniq(miss_list($e_len+1, map(substr($g,0,$_).".".substr($g,$_+1), (0..$g_len-1))))); } else { push(@R, $g); } } @R; } sub transpose_list { my @R = (); my $g; foreach $g (@_) { my $g_len = length($g); push(@R, uniq(map(substr($g,0,$_-1).substr($g,$_,1).substr($g,$_-1,1).substr($g,$_+1), (1..$g_len-1)))); } @R; } ## examples ## fetch some words #chop(@l = (<>)); ## regexps for if one letter was omitted #print(map($_."\n", omit_list(+1, @l))); ## regexps for if one extra letter was added #print(map($_."\n", omit_list(-1, @l))); ## regexps for if one letter was screwed up #print(map($_."\n", miss_list(-1, @l))); ## regexps for if two letters were transposed #print(map($_."\n", transpose_list(@l))); ## possible matches if one letter were omitted #print(map($_."\n", omit_list(-1, @l))); ## possible matches if two letters were transposed #print(map($_."\n", transpose_list(@l))); ## check for possible collisions if one letter were omitted #print(map($_."\n", nonuniq(omit_list(-1, @l))), "\n"); ## check for possible collisions if two letters were transposed #print(map($_."\n", nonuniq(transpose_list(@l))), "\n"); # end

Daily WTF!にも載るのかなこれ。

2011年5月4日水曜日

雇用体系、労働者の権利、業界の成長...

(諸般の事情により書きなおし)

今回のシアトル訪問はクラウド関係者の集まりへの参加が目的。昨日は準備運動で、今日から本番。

そのクラウド提供事業者の人達と話していて改めて思い出したのは、

  • 比較的新しい事業にも関わらず、事業面・技術面それぞれで「プロフェッショナル」を揃えている。
  • 各自、自分の守備範囲が明確で、その範囲内ではかなりの裁量を任されている。つまり判断から執行までが早い。
  • 人事採用権限は各部門の長がもっている。
等々。

「こういう人材が欲しい!」という要望を各部門は明確に描けるし、それに適合した人を自分たちで探せるというのは素晴らしい。人事部という間接部門(しかも技術や事業の専門家集団とは言えない)を挟まなくていいわけだ。結果として

  • 新規事業を立ち上げる助走期間が減る=機会損失回避
  • その事業に不適合な採用を減らせる=利益率向上
という効果が得られる。反面、成果をあげられなかった人はあっさりと解雇されるかもしれない。また、事業がうまくいかなかったらその部門まるごと畳まれる可能性もある。

そして雇用をささえる仕組みを企業側が持たないというところがミソなわけで。採用したけど仕事に不適合だから別部門に移動してもらってなんだかよく分からない仕事を与えて給与を払い続けるなんてことはない。要は実力に見合った仕事さがして頑張れ、と。

当然、終身雇用なんてのは有り得ないし、大卒即正式採用なんてのは珍しい話になる。若いうちは、トレーニーや下積み前提の雇用で働くことが前提となるかもしれない。結果として、学生からは「不人気業界」という烙印を押される事になる。

だがドットコムバブルの頃のような「売り手市場の雇用」というのは、実力に見合わない給与の人達を業界全体が大量に抱えることになりかねないわけで。実際そのとおりになってしまったので、業界全体がインドなどへのオフショア移転を推進したという面はあるだろう。

でも、そういう「自浄作用」が機能するというのは、米国のソフトウェア業界がまだ健全であることを示しているということでもある。



私が働いているコンピュータ業界は、個人の能力が重視される。学歴は二の次だ。これこそ、コンピュータ業界が常に革新的で、進化を続ける原動力であろう。窮屈な官僚主義も利権主義のゴマすり連中も、コンピュータ業界の創造性や破壊的想像力を浸食するには至っていない。今のところは、ね。
まさにこの記述のとおりなんだな、と。

2011年4月29日金曜日

code記述

これは便利