Hatena::ブログ(Diary)

山本大の日記 RSSフィード Twitter

株式会社レベルエンター(http://levelenter.com/)で、プログラミングを若手に教える仕事をメインにやっています。

2013-03-18

8つの質問で、Java SI業界の現状を知る

Webサービス系の会社の隆盛があって、人材流出が騒がれたのが1−3年ぐらい前だろうか。
SIの産業の人材動向が、今どうなってるかって?

大方の予想より凄惨ですよ。

それが分かる方法がある。JavaWeb技術者技術力を問う8つの質問によってだ。
SI業界のエンジニアの平均レベルを知りたくって、いろんな会社さんのJavaWeb開発者経験者)向けに以下のような8つの質問を継続的にしている。
対象者としては、Java経験3から10年ぐらいの現役バリバリのはずのJavaエンジニアだ。

その8つの質問というのはこんな問題だ。

JavaWeb技術者に技術力を問う8の質問

  1. インターフェイスメリットを一言で表して下さい。(筆記解答)
  2. HttpRequestオブジェクトからPostされたデータを取得するServletメソッドは何ですか?(筆記解答)
  3. Sessionのスコープを端的に説明してください。(筆記解答)
  4. JNDIを使ってJDBCデータソースを取得するためのコードはどれですか?(選択解答)
    1. DataSource ds = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/SampleDS");
    2. DataSource ds = (DataSource)new InitialContext().getDataSource("java:comp/env/jdbc/SampleDS");
    3. DataSource ds = (DataSource)new JNDIContext().lookup("java:comp/env/jdbc/SampleDS");
    4. DataSource ds = (DataSource)new JNDIContext().getDataSource("java:comp/env/jdbc/SampleDS");
  5. 結合テスト中のシステムで、OutOfMemoryErrorが発生しました。UTソースコードの変更はしていません。ヒープメモリは足りているようです。原因として何が考えられますか?(筆記解答)
  6. String オブジェクトを+で結合するのはなぜNGなのかメカニズムを説明してください。(筆記解答)
  7. HTTPクライアントブラウザの種類などの情報を知るためのヘッダは何ですか?(筆記解答)
  8. JavaScriptHTML要素をid属性の指定により取得するメソッドは何ですか?(筆記解答)

過去に実施した平均点

この8問について、僕が出会ったエンジニアに解答してもらった平均正解数は、
なんと8点満点中1点である。

内訳的な話

うろ覚えになってしまってるだろうから満点は無理でも、ちゃんとJavaをやってるエンジニアさんであれば4問は解けるだろう。
筆記解答については相当甘くつけるから尚更だ。
例えば、1問目「インターフェイスのメリット」は、「疎結合の実現」ならニジュウマルだが、「層ごとの役割分担」でも「仕様の強制」でも「ポリモフィズムの実現」でもマルで、それらに類する説明ならちょっと分かりにくくても、なんでも正解にしてる。

OutOfMemoryの問題は、経験していなかったから知らないから何も言えなくてもまぁいいだろう。
(10年やっててもOOMの込み入ったトラブルを経験しないなんて運がいい人なのだろうか、悪い人なのだろうか)
「getElementById」なんてほとんど白紙解答。
「Stringはおまじない的に+でつなげちゃダメと思うようにしている」
「StringBufferを使うべきと教えられたから」
そんな状況である。1、2年目ではなく3−10年生であり、PGバリバリとの触れ込みなのだ。
設計やチームリードコミュニケーションを得意としている人ではない。プログラマー対象なんだぜ。
(ウチの会社では平均5.5点ほどあった。これは基礎教育をやってれば当たり前の点数だろう)

これぞ現在のSI業界の実態

でも僕は、ここ数年東京でSIのエンジニア提案などの営業をやっていた経験から納得がいく。
これぞ「労働集約産業である現在のSI業界の実態」なのだから。

基礎教育なしに、1年目0円でテスト要員→2年目ちょっとPHPとか→3年目Java
仕事と割り切った中で、フレームワークに乗っ取ったコードを書き続ける→その後10年経過
という流れのキャリアパスを通ってきた人に山ほど出会ってきた。

そういう人ほど、この業界で生き残っている現実ではないか。

淘汰の進まない業界

統計としては母数が少なすぎる(2桁程度)「し」母集団を変えれば別の所感が得られるだろう。
しかしながら、ヤバいのは淘汰が進まない事だ。
特に東京は仕事量も多いから、こういうレベルの人でも危機感なく生き残ってしまう。
このところ景気がいいせいもあって、正解数1問だった人もすぐに稼働現場が決まって行ってるようだ。
こういうエンジニアたちが大勢集まってシステム開発をするのだ。

結果として、一部の出来る人には余計に負荷がかかるだろうなと思う。

いままで僕は楽観主義者だから、

SIは労働集約産業だったけど、これからは知識集約産業になっていく。
必然的に淘汰の時代になり、優秀な人が生き残るだろう。

と思っていた。

しかし現実は、もっと凄惨な世界を経て時代が進んでいくようだ。






蛇足な追記

ブクマとかで8つの質問に答えてくれる人がいたり、いろいろ言う人もいるので御答えします。

「Stringを+で連結しても、一行で書かれていればコンパイラ最適化してStringBuilderに置き換えますよ。」系の答えをしてる人は、良いとこ行ってるけど残念ながら0.5点
こういう人は、現場で直面してないし机上で知ってるレベルだ、
デコンパイルしたり、現場で直面したりすると如何にJDKの最適化が大した事ないか思い知る。

例えばこの程度のコードをデコンパイルしてみる。

public class Main {
	public static void main(String[] args) {
		String s = "";
		for(int i=0;i<10;i++){
			s = s + i; 
			System.out.println(s);
			
		}
	}
}

JDK7でコンパイルしてデコンパイルするとこうなるんだぜ。結局+の動きなんだよね。

import java.io.PrintStream;

public class Main
{
  public static void main(String[] args)
  {
    String s = "";
    for (int i = 0; i < 10; i++) {
      s = s + i;
      System.out.println(s);
    }
  }
}

でもこのレベルのコードの統制は、いまのSIのエンジニアレベルでは効かない事を見越して、悪と断じるなら3点あげるね。
メカニズムを質問してるのに真正面から回答してないのもマイナス点。
1行内のString+なんてそもそも問題にならない。それはメカニズムを知ってこそわかる。


5番目の問題はやや難問。コメントで「ループ処理もしくは再帰処理内でオブジェクトの生成が原因かも」と答えて頂いたが、これは非常に惜しい。
ヒープは足りてるというのがミソであり、OOMが出てるのもミソ。
ヒープは足りてるのでヒープのリーク系は軒並みアウト。
再起が走りすぎてる系は、StackOverFlorwが先に出るのでアウト。
この問題は、JSPをやたら使うシステムで、JVMメモリ管理をうまくやってないか、
S2のホットデプロイJenkinsなどのCIをやると直面する問題。

ヒントはPermanent領域



次、「SIをプログラミングと思ってるわけか。」系は、単文すぎて意図は読みかねるけど僕は、プログラミングの最低レベルを切ろうと思っている訳で、ソリューション分析や設計の価値は認めてる。でもソリューション提案するにしても技術の根本的な知識がなければ机上の空論が多すぎるでしょって言いたいな。


「ググれば良いじゃん」的な回答の人は、ググったことあるけど頭に残ってない系であることを宣言してるにすぎない、
同じ事案にたいしても毎回ググっちまう非効率の権化。
僕は、覚えてることを相互的に脳内シナジーをあたえ価値を生み出すことが人間の人間たる価値だと思う
ググるに頼る率の高い奴こそ労働産業の申し子となっていくだろう。


8問目がJavaScriptなのは、意図的。Java経験者でもJSをやってない人はめちゃくちゃ多い。
僕からするとJavaでバッチだけやってましたはJava経験者とは言わない。
だから、あえてJSの問題を入れる。だってJavaやっててJS触れてないっておかしいでしょ。
僕はこの8問でJavaWeb技術者を診断したくて、OCJ-Pをやりたいとは思ってない。


言語依存の設計ができる方が大事そうだが。」ってブコメきたけど、、、「言語比依存の設計」の価値って、「言語を考慮した設計」の価値を超えます?僕は少なくともパフォーマンス面で超える気がしないけどな。

774774 2013/03/18 19:35 高尚な方々の考えることはわからないねw

1)実装時の、必須メソッドの強制化によるメンテナンス性の向上
2)doPost
3)同一ブラウザ間、タイムアウトまで
4)DataSource ds = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/SampleDS");
5)ループ処理もしくは再帰処理内でオブジェクトの生成が原因かも
6)VM側で最適化されるから余り問題じゃないかも。古いVMならStringのインスタンス化が行われるから
7)User-Agent
8)getElementById (これjavaじゃないじゃん)

nkgt_chkonknkgt_chkonk 2013/03/18 23:05 母集団と標本を取り違えてないでしょうか。
本筋とは関係ありませんが気になったので。

iad_otomamayiad_otomamay 2013/03/19 00:34 774さん
1) 正解
2) 残念(ヒント「Postされたデータ」を取得する)
3) 正解
4) 正解
5) 0.5点(ヒント本文追記で記載)
6) 残念 メカニズムを答えて欲しいし、JDK7.0だろうが問題は依然としてある。
7) 正解
8) 正解(JSであるところも正解だけど、Java[Web]エンジニアのレベルを問う意味で趣旨違いではないですよね)

774さん 5.5点

iad_otomamayiad_otomamay 2013/03/19 00:35 nkgt_chkonk さん
母集団と標本は認識してましたが、ちょっとニュアンスを間違えました。
書き直します。指摘ありがとうございます!!!

ss 2013/03/19 01:15 一過性の細かい不具合を覚えるってのは
ISO的にはそんなにレベルの高い方じゃないよ

新入りが不具合見つけてちょっと聞いただけでも
すぐ直るような体制があるとか言う方がプロっぽい

popcornpopcorn 2013/03/19 04:34 iad_otomamayさんは、お偉い方達が低脳・低スキルを切らないのは何故だと考えていますか? 御社クロノスは低スキル者は解雇をし採用もしないのでしょうが、外注される時はどうされているのでしょうか。

馬鹿ばっかりでイヤになる!と日頃の鬱憤を述べられるのは悪い事とは思いませんが、本やググって勉強をやってれば自ずと十分なスキルが付くとは俺は思いません。
俺はiad_otomamayさんのブログはこれが始めてですが、ご自身の仕事や勉強に対する意識が高く自負があるから仰っているのでしょうが、点数が取れなかった人や指摘されている事に心当たりある人はどうすれば良いかという提案は多少なりとも書いて頂きたかったです。そんな甘えを言う奴は明日退職届を出せと仰られるのかもしれませんが・・・

kiya2015kiya2015 2013/03/19 07:25 技術的に不足している技術者が業界に多いことは確かだと思います。
ただ、その業界に余裕がない以上、
「もっと教育をしろ」と提言しても、その結果は「休日自主勉強会」のような
末端労働者へのしわ寄せというカタチでやってきます。
そしてそれすらできない無能は死ねというマッチョイズム、ネオリベ的な議論になっていく。
これでは誰も得しないでしょう。

叩くべき、淘汰すべきなのは馬鹿な技術者ではなく
エクセルに人月計算を書くだけで自分は大きな仕事をしたと勘違いしている人たち、
肩書きだけで内実は商社マン気取りの技術者ですらない人たちのほうではないですか?

kiya2015kiya2015 2013/03/19 07:32 「給料は上げない、でももっと精進しろ」
鞭だけ与えてもそんな組織は支持されないし、
飴を与えてくれるほうに逃げてしまう。
それがSIerからソーシャルゲームへの流れを生み出しています。

これは、韓国や台湾企業へエレクトロニクスの先進技術者が流出し、
日本の旧来企業の技術レベルが低下していっているのと同じ話です。
本質は待遇の良し悪しであり、経営判断の誤りです。
「近頃の部下は馬鹿が増えましたね」と悦に入っている上層部こそ馬鹿なのです。

kiya2015kiya2015 2013/03/19 07:58 あと、技術的なことですが、この質問群は「正しいけれどちょっと古い」のではないでしょうか?
もちろんフレームワークによらないサーブレットやJNDIの仕様を理解しておくのは重要ですが、
新しい技術を吸収していくのも良い技術者で居続けるためには欠かせないことです。
その点で、1.4以降の仕様(総称型やアノテーション)やjavascriptのクロージャ、jQueryのon/off関数などの
質問が加わればもっといいのではないかと思いました。

長々とお目汚しすみません。これで失礼します。

rey1229rey1229 2013/03/19 09:19 ユーザ系SIerでこの点数なら合格ではないかな。。
1)正解
2)正解
3)正解
4)分からなかった
5)半分正解
6)正解
7)残念
8)正解

774774 2013/03/19 09:47 あ、採点されてる。
ありがとう!

2)getParameter multipart だったらgetInputStreamでパース
はやとちったのかw

5)Perm領域不足
普段
-XX:PermSize=256M -XX:MaxPermSize=256M
っていっぱいあげてるから考えもしなかった
OOMの前にFull GC連発したりしないの?

6)「Stringは実は連結できない」ため +すると実は新しいインスタンスが作られるので遅いしメモリ的にも良くないから
javacコンパイラの最適化じゃなくてJITコンパイラの最適化はStringには行われないのかな?

iad_otomamayiad_otomamay 2013/03/19 10:37 popcornさん ここまで低スキルの人が生き残ってるというのはPGさんの過失ではなく、経営的な問題だと思います。
クロノスは、ほとんど未経験者を採用してます。そして一人前になるまで徹底的に教育をします。教育を事業としてやってる会社ですから。
上記のような状況をしってるのでパートナー会社さんと協業するときは、非常に慎重です。あと自分たちの力量を越えて大きな案件は取りません。
提言としては、こういう現場で目にしない基礎中の基礎を「現場で使わないからどうでも良い」と思わずに、触れた技術には根本的な興味を日々持って仕事をしてほしいという事でしょうか。

iad_otomamayiad_otomamay 2013/03/19 10:48 kiya2015 さん
おっしゃる通り、いろんな会社さんの経営判断のまずさや慣習通りの仕事の進め方によって、業界が悪くなっている部分があると思います。それは昔からSIを「労働集約産業」と位置づけている経営者が多く、いまだにその認識だからだと思います。
これからはそういうことではやっていけなくなり、知識集約産業になっていくでしょう。
これまで大勢のエンジニアで割り算していた売上げと利益を少数の出来るエンジニアと正しい姿勢の会社が享受できるようになると、この業界は明るくなると思うんですよね。その業態は、もはやSaaS提供となってるかもしれないですが。
JDK5以降の設問は確かに加えた方がいいかもしれませんね。ありがとうございます。JSはこの設問群では主眼ではないのでクロージャまで知らなくても、まぁいいかなと思ってます。JQueryも同じく。

iad_otomamayiad_otomamay 2013/03/19 11:07 rey1229さん
素晴らしい!

KIMNYKIMNY 2013/03/19 11:20 1.業務ロジック以外余計な実装すんな宣言
2.HttpServlet#doPost(HttpRequest これ, HttpResponse へんじ)
3.リクエスト単位や、コンテナ単位で、場合に応じて生存状態を好きに定義する為
4.DataSource ds = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/SampleDS");だっけ?あんま回数書かないと忘れるな・・・
5.複数インスタンス生成されたら足りなくなった系?SingleThreadModelだったら後に地獄になるな・・・
6.毎回newされっからって事?演算処理って、Javaのバージョンによりコンパイル時にバージョンに適した最適化されるのと可読性の向上としてNGな理由よりメリットの方が多いと思うの、わたし
7.などってのが引っ掛け問題なのかしら?UserAgent、Via、後は何だ・・・Referer?
8.getElementById()だっけ?JScript,JavaScript,ECNAScript全部で使える・・・と思ったからこれかな(自信なし

・・・これ答えた=Javaエンジニアとは思わんけど
現場監督にはなれるかなぁ

iad_otomamayiad_otomamay 2013/03/19 11:33 774さん
2)正解ですね!
5)開発環境とかで適当にTomcatなんかを立てると出ちゃいます。それをスルーするか突っ込んで調べるかの違いが分かる問題かもしれまん。ちなみにFullGC出まくります。ご明察!2点。
6)正解ですね。模範は以下「Stringオブジェクトは、内部でChar配列として文字を持っており不変長である。+記号によるStringの結合は、ヒープ上では参照の付け替えであり。古い文字列と結合によって作られる新しい文字列の両方をヒープ上で持つことにより、メモリの圧迫、ひいては大幅なパフォーマンス劣化を引き起こす可能性がある。」

標準JREのJITは何もしてくれない。
以下試してみると良いですよ。

import java.util.Date;


public class Loop {
public static void main(String[] args) {
Date start ;
Date end;
int loop = 50000;
start = new Date();
String s = " ";
for(int i =0;i<loop;i++){
s = s + i;
}
end = new Date();
System.out.println("s+");
System.out.println(end.getTime() -start.getTime());

start = new Date();
StringBuilder sb = new StringBuilder(" ");
for(int i =0;i<loop;i++){
sb.append(i);
}
end = new Date();
System.out.println("sb");
System.out.println(end.getTime() -start.getTime());

}
}

iad_otomamayiad_otomamay 2013/03/19 14:42 KIMNY
1.まぁ正解w
2.残念(ヒント「Postされたデータ」を取得する)
3.残念(スコープとは範囲の意味なので)
4.正解
5.0.5点ちょっと違う気がするけど、感じられるものがある
6.0.5点おしいでも面白い問いかけ。String+は可読性のために犠牲にするには大きすぎる劣化があります。
7.正解(引っかけはあんまりなかったです)
8.正解

5点ですね

・・・これ答えた=Javaエンジニアとは僕も思ってないですよ。
どんなもんか知りたいだけで。

popcornpopcorn 2013/03/19 16:11 コメント有難うございました。
これは俺がiad_otomamayさんのニュアンスを受取れてないのでしょうが、だったら部課長クラス以上の傾向分析、批判と改善点、改善見込みについて語って欲しかったです。

労働集約産業という表現に馴染めないのですが、昔から言われているIT土方ってことですかね。知識集約に向かうと仰っていますが俺はそうは思いません。なぜなら役職者の多くが「ググっとけ」と言って教えない。勉強は自分ですることだから甘えるなって言いたいのでしょうが、それは違うと感じます。
勉強しない人を救えとは言いませんが、「出来る人以外は排除」は知識集約に向かう手段として良いかも知れませんが、如何なものかなと思います。

知識集約化を希望されていますが、日本はずっと労働集約のままだと思います。
1社が知識集約化されても意味がない。アウトソースに比重が置かれている現状を見れば、社員教育を受けて育つ人が減る。また出来る人さえ首切る某社では解雇者が韓国企業に流れて技術流出してしまう。知識集約化できる土壌にあるとはとても思えません。
本当に知識集約化させるのなら、幼稚園や小学校から叩き込ませる。基本情報は中学高校で取得させるくらいの国の教育政策が必要になってくるのではないでしょうか。俺の知る限りではIT特化の中学高校は聞いたことがないです。(高専にはあるでしょうが)
後半愚痴になってしまい失礼しました。

理者理者 2013/03/19 21:40 5.以外は簡単だった。
中小のSIで入社からプログラミングやってからのSIになっているので、
この程度であればほぼ解ける。

最後のほうに書いていることよくわかんなかったけど
「ソリューション提案するにしても技術の根本的な知識がなければ」は激しく同感。

今、他の会社のSIと一緒にやってるけど、
技術も知識もなくて、何を提案するのかっていつも思うような人たちだから、ホント使えない。(もちろん勉強もしてない)

774774 2013/03/20 04:00 > 模範は以下「Stringオブジェクトは、内部でChar配列として文字を持っており不変長である。

Javaは知らんけど、個々のオブジェクトインスタンスの持つChar配列は異なるんじゃ
ないの?というか、C/C++だとクラスは自由に定義できるからぶっちゃけ実装依存な
わけだが、JavaのStringクラスって、プリミティブ型なのか?

> 例えばこの程度のコードをデコンパイルしてみる。
> <Snip>
> JDK7でコンパイルしてデコンパイルするとこうなるんだぜ。結局+の動きなんだよね。

System.out.println(s); がforループ内にあるのでは、最適化はできないのでは?

String s[10] = {"\x0", ... ,"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9"};
for(int i=0;i<10;i++)
  System.out.println(s[i]);

みたいな最適化を期待しているのなら、まず無理ぽ。(w

System.out.println(s); がforループの外にあったら、forループが展開されて、

String s = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9";
System.out.println(s);

とでもなると期待されているんでしょうかね?

c/c++等であっても、forループによる文字の連結を、初期化済み固定文字列の
代入に置換してくれるような最適化を実装した処理系は存在しないと思う。

10年生10年生 2013/03/22 09:45 問2の文章「Servletのメソッド」という文章が誤解を招く可能性があります。
javax.servletパッケージなどの「Servlet API」を指すのか、
それともその中のjavax.servlet.Servletインタフェースを指すのか
あいまいです。

前者と解釈すれば、山本様の考えるとおりの答えでいいですが、
後者と解釈すると、ServletRequest#getParameter()やServletRequest#getInputStream()は、
いずれもServletRequestのメソッドであり、「Servletのメソッド」という文章に沿いません。
あえて挙げるならHttpServlet#doPost()になりますが、
これはjavax.servlet.Servletではなくjavax.servlet.http.HttpServletのメソッドですし、
それにコメントでのやりとりを見るに、それは意図した回答ではないのですよね。

もっというと、「Postされたデータを取得」というのも曖昧です。
ServletRequest#getParameter()のドキュメントには以下のように記載されており、これを持って正解と主張することは可能です。
http://docs.oracle.com/javaee/1.4/api/javax/servlet/ServletRequest.html#getParameter(java.lang.String)
| For HTTP servlets, parameters are contained in the query string or posted form data.

バイナリデータを取得したいと明記すれば、こういった曖昧性は排除されたでしょう。

もっと単純に、「フォームから送信された添付ファイルを取得するコードを書け、ただし標準のサーブレットAPIのみで」くらいでよかったんじゃないでしょうか。
ただ、HTTP マルチパートの扱いも含まれるので、難易度がはね上がりますが。

PJFSPJFS 2013/03/22 10:44 ハイスキルの人はフラストレーション抱えたり背比べするんじゃなくて
その相手でも出来るように分解して仕事を投げるとか

toris-birdstoris-birds 2017/07/18 01:04 Java屋さんではないですが、ひねくれた突っ込みを。

> インターフェイスのメリットを一言で
> 「疎結合の実現」ならニジュウマルだが

「疎結合の実現」だけだと、多重継承っぽい事ができるという面が抜けているような気がします。疎結合の実現だけなら、極端な話、abstract classなどでもいいのでは?という疑問が出てくるかと思います(「インターフェイスの」と限定できない)。むしろ、最小限必要なものを、ある程度まとまった単位ごとに管理できる(それも複数追加できる)点の方がインターフェイスのメリットなのでは?とも考えられます。
なので、一言で言い表すのは少し無理があるような気がします。

> String オブジェクトを+で結合するのはなぜNGなのか

一般論で言えばNGですが、条件によってはOKかと思います。
長い文字列を連結して、動的に生成する(生成後の文字列が事前(コンパイル時)に決まる文字列でない)場合は、文字列を作り直すコスト的にNG。
ただし、極端に短い文字列で、結合回数が少ない場合だったりすると、StringBuilderの類が内部に持っているバッファ(実装によるとは思いますが4kなど)の生成コストの方が大きくなるのでは?と思ったりもします。(StringBuilderを毎回生成しない条件なら別ですが)
あと、StringBuilderから結合した文字列を出力するコストも考える必要があるかと思います。(内部バッファにため込んだ文字データと長さを元に、新しい文字列を生成するのでは? 言い換えると、連結回数が少なければ、新しい文字列の生成をするからNGとは言えないのでは?)
例えば、final static String str = "a"+"b";のような場合は、どうでしょう?

とか回答して、先生を困らせるエンジニアが居てもいいと思う今日この頃。
想定した答えを求める教育が技術者のレベルを下げてきたんじゃないかなと個人的には思います。障害などに直面してどれだけ物を考えて来たか、って事が分かる質問が多めだといいかもしれませんね。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証