業務系のJavaプログラマーが知っておくべき10個のBad Partsとその対策 - 達人プログラマーを目指して
自分はよくこうする。

try {
    Writer out = new BufferedWriter(new FileWriter("ファイル名"));
    try {
        // なんやかんや
    } finally {
        out.close();
    }
} catch(IOException e) {
    e.printStackTrace();
}

まあ、これだと結構深刻な欠点があるんだけど。

SIer に足りないものは

google なり apple なり、あるいは dwango なり gree なり、技術者を大事にしている*1会社と、昔ながらの老舗 SIer では、その構成員が大分異なるんじゃないかという考えに至った。前者は社員を技術者として、個人の能力に依存するが一騎当千の強者を大事にする。一方後者は社員を従業員として、凡人〜秀才を多数集めて集団を形成する。
SIer の構成員は普通のサラリーマンだ。たくさん寄り添い助け合い、知恵を絞りあって普通のシステムを作る。1年や2年、あるいはもっと長い時間をかけて。

遅いことなら誰でも出来る!
20年かければ馬鹿でも傑作小説が書ける!

つまり、日本の SIer に足りないものは明白だ。

お前に足りないのはッ!情熱思想理想思考気品優雅さ勤勉さ!
そして何より――

速 さ が 足 り な い ! 

と、ここまで思考を暴走させて、意外と的を射ているなぁと思った次第。

*1:ような雰囲気のある

DIコンテナを作っています。相談に乗ってくれる人を探しています。

http://code.google.com/p/freja/
できることは少ないが覚えるべきことも少ない。最低限動かすなら3つだけで十分。

  1. インタフェイスと、その実装クラスを用意する
  2. 実装クラスに @Component アノテーションを付ける
  3. インタフェイスの Class オブジェクトで get する
public class FrejaSample {
    public void main(String[] args) {
        Animal animal = Freja.get(Animal.class);
        animal.bark();
    }

    private interface Animal {
        public void bark();
    }

    @Component
    private static class Cat implements Animal {
        public void bark() {
            System.out.println("meow meow");
        }
    }
}

これだけ。利点は幾つか。

  1. 既存のオブジェクトに後付で DI する方法もある。テストケースへの DI も、変なクラス継承など無しにメソッド1発
  2. コンポーネントのスコープが意外と豊富。メソッド呼び出し1回の間だけ生存するコンポーネントも作成できる

残念ながら、懸念点も幾つか。

  1. アノテーションだけで出来ることは、コンポーネント登録と、フィールドインジェクションのみ
  2. マイクロベンチマーク取ってみたら、速度が S2 の十分の一程度
  3. 1個の jar だけで完結させようとしたら、外部の有意義なライブラリ*1が全く使えなくなった

早くも行き詰まり感を感じていたり……スランプなのかなぁ。今の自分だけでは先に進めそうにないので、こんな変なものの相談に乗ってくれる人をさりげなく募集していたりします。

*1:javassist とか aopalliance とか

文法を一日ででっち上げる

やっぱり yacc は書いてて楽しいね。LR だと LL よりも素直にかけてストレスが少ない。
微調整は必要だと思うけど、まあ追々直していこう。

%{

package caitsith.parser;
import java.io.*;

public class Parser {

%}

// 構造キーワード
%token      ACTOR, PROCEDURE, VAR, IS, END
// 制御構造キーワード
%token      IF, THEN, ELSE, FOR, WHILE, DO, TRY, CATCH, FINALLY, SWITCH, CASE, ASSERT
// 制御構文キーワード
%token      INC, DEC, BREAK, CONTINUE, THROW
// 演算子
%right      ASSIGN, ASSIGN_ADD, ASSIGN_SUB, ASSIGN_MUL, ASSIGN_DIV, ASSIGN_MOD
%right      QUESTION, COLON
%left       OR
%left       XOR
%left       AND
%nonassoc   EQ, NEQ
%nonassoc   LT, LTEQ, GT, GTEQ
%left       IFNULL
%left       PLUS, MINUS
%left       MUL, DIV, MOD
%right      NEG, NOT, NEW
%token      DOT, RIGHT_ARROW, RIGHT_DOUBLEARROW
// 記号
%token      LP, RP, LB, RB, LBT, RBT, LST_LBT, MAP_LBT, SET_LBT
%token      COMMA, SEMICOLON
// 変数
%token      NAME, SELF, FIELD, JAVANAME
// リテラル
%token      SYMBOL, NUMBER, STRING, CHAR, NULL, VOID, TRUE, FALSE
// その他
%token      EOF

%%

compilationUnit:
    defActorList EOF
    ;

// アクタの定義
defActorList:
    | defActor defActorList
    ;
defActor:
    ACTOR fullname defArgument IS defProcedureListOpt END
    ;
defArgument:
    | LP RP
    | LP fieldList RP
    ;
defProcedureListOpt:
    | defProcedureListOpt defProcedure
    ;
defProcedure:
    PROCEDURE patternList IS stmtListOpt END
    ;

// 文の定義
stmtListOpt:
    | stmtList
    ;
stmtList:
    stmt
    | stmtList stmt
    ;
stmt:
    name COLON stmt
    | SEMICOLON
    | expr SEMICOLON
    | exprAssign SEMICOLON
    | expr exprList SEMICOLON
    | INC variable SEMICOLON
    | DEC variable SEMICOLON
    | INC variable COMMA expr SEMICOLON
    | DEC variable COMMA expr SEMICOLON
    | BREAK SEMICOLON
    | BREAK name SEMICOLON
    | CONTINUE SEMICOLON
    | CONTINUE name SEMICOLON
    | THROW SEMICOLON
    | THROW expr SEMICOLON
    | IF expr THEN stmtList END
    | IF expr THEN stmtList ELSE stmtList END
    | FOR name ASSIGN expr DO stmtList END
    | FOR name ASSIGN expr DO stmtList ELSE stmtList END
    | WHILE expr DO stmtList END
    | WHILE expr DO stmtList ELSE stmtList END
    | TRY stmtList CATCH name DO stmtList END
    | TRY stmtList FINALLY stmtList END
    | TRY stmtList CATCH name DO stmtList FINALLY stmtList END
    | SWITCH expr caseList
    | ASSERT expr SEMICOLON
    | ASSERT expr ELSE stmtList END
    ;
caseList:
    caseBody
    | caseList caseBody
    ;
caseBody:
    CASE pattern THEN stmtList END
    ;

// 式の定義
exprAssign:
    variable ASSIGN expr
    | variable ASSIGN_ADD expr
    | variable ASSIGN_SUB expr
    | variable ASSIGN_MUL expr
    | variable ASSIGN_DIV expr
    | variable ASSIGN_MOD expr
    ;
exprList:
    expr
    | exprList expr
    ;
expr:
    term
    | NEG expr
    | NOT expr
    | expr MUL expr
    | expr DIV expr
    | expr MOD expr
    | expr PLUS expr
    | expr MINUS expr
    | expr IFNULL expr
    | expr EQ expr
    | expr NEQ expr
    | expr LT expr
    | expr LTEQ expr
    | expr GT expr
    | expr GTEQ expr
    | expr AND expr
    | expr XOR expr
    | expr OR expr
    | expr QUESTION expr COLON expr
    ;
term:
    variable
    | SELF
    | primitive
    | LP expr RP
    | LST_LBT listElementOpt RBT
    | MAP_LBT mapElementOpt RBT
    | SET_LBT listElementOpt RBT
    | term RIGHT_ARROW name
    | term DOT name LP listElementOpt RP
    | term LBT expr RBT
    | NEW fullname LP listElementOpt RP
    | NEW javafullname LP listElementOpt RP
    ;
listElementOpt:
    | listElement
    ;
mapElementOpt:
    | mapElement
    ;
listElement:
    expr
    | listElement COMMA expr
    ;
mapElement:
    expr RIGHT_DOUBLEARROW expr
    | mapElement COMMA expr RIGHT_DOUBLEARROW expr
    ;

// 変数の定義
variable:
    name
    | field
    | javaname
    ;
fullname:
    name
    | fullname DOT name
    ;
name:
    NAME
    ;
fieldList:
    field
    | fieldList field
    ;
field:
    FIELD
    ;
javafullname:
    javaname
    | javafullname DOT name
    ;
javaname:
    JAVANAME
    ;

// パターンの定義
patternList:
    pattern
    | patternList pattern
    ;
pattern:
    primitive
    | name
    | wildcard
    | LST_LBT patternListElementOpt RBT
    | MAP_LBT patternMapElementOpt RBT
    | SET_LBT patternListElementOpt RBT
    ;
patternListElementOpt:
    | patternListElement
    ;
patternMapElementOpt:
    | patternMapElement
    ;
patternListElement:
    pattern
    | patternListElement COMMA pattern
    ;
patternMapElement:
    pattern RIGHT_DOUBLEARROW pattern
    | patternMapElement COMMA pattern RIGHT_DOUBLEARROW pattern
    ;
wildcard:
    QUESTION
    ;

// プリミティブの定義
primitive:
    SYMBOL
    | NUMBER
    | STRING
    | CHAR
    | NULL
    | VOID
    | TRUE
    | FALSE
    ;


%%
    public static void main(String[] args) throws IOException {
        FileReader source = new FileReader(args[0] );
        Scanner scanner = new Scanner(source);
        Parser yyparser = new Parser();
        try {
            yyparser.yyparse(scanner);
        } catch (Parser.yyException ye) {
            System.out.println(ye);
        }
    }
}

78 terminals, 35 nonterminals
129 grammar rules, 263 states

【悪夢】 リンクをクリックするとサーバにリクエストが届き、PDFファイルが自分のメールアドレスに送られてくる

という機能を運用で執り行なう。

RE: IT業界の景気はいつ回復する?

ということで IT業界の景気はいつ回復する? | 日経 xTECH(クロステック) に答えてみた。僕の回答を貼り付け。

  • 質問: あなたの立場を教えてください。
    • 回答: IT製品/サービスを“提供”する立場
  • 質問: 今年後半、IT業界の景気はどうなると思いますか?
    • 回答: やや厳しくなる
  • 質問: 日本のITベンダーは全体としてまだ厳しい状況にありますが、海外の主要ITベンダーは最近好業績を上げています。日本のIT業界には構造的な不況要因があると思いますか?
    • 回答: あると思う
  • 質問: Q3で「あると思う」と答えた方にお聞きします。どのような構造的不況要因があると思いますか? あてはまると思うものをすべて選んでください。
    • 回答: 世界に通用する日本発のイノベーションがない、日本製のIT製品/サービスには国際的な価格競争力がない、その他
  • 質問: その他
    • 回答: 国際的な技術競争力がない。技術向上精神が特に薄い。
  • 質問: Q1で「IT製品/サービスを“提供”する立場」と答えた方にお聞きします。あなたの会社では、この不況を乗り越えるためのビジョンや戦略を明らかにしていますか?
    • 回答: ビジョン/戦略はあるが、その有効性には疑問を感じている
  • 質問: Q1で「IT製品/サービスを“提供”する立場」あるいは「IT製品/サービスを“利用”する立場」と答えた方にお聞きします。クラウドコンピューティングSaaS、PaaS、IaaSなど)が急速に広まりつつあります。このクラウドコンピューティングは、今後、あなたの仕事やあなたの会社の業績に影響を及ぼすと思いますか?
    • 回答: 悪い影響を及ぼすと思う
  • 質問: Q5で良い影響あるいは悪い影響を及ぼすと答えた方にお聞きします。具体的には、どのような影響があると思いますか? 自由にお書きください。
    • 回答: SIer が「オープン化」や「ASPの波」を受け入れた時と同じ匂いを感じます。それらを受け入れた時と同じ失敗を繰り返し、曖昧な理解による中途半端なシステムばかりを世に送り出すことになるのではないかと不安に思っています。このままではオープン化の二の舞になります。そもそも国内ITベンダはクラウドについて無知の状態からのスタートです。生粋のクラウドベンダは自分に有利なようにルールを作れるため、その枠内で戦う以上、いくら努力しても勝つことはないでしょう。
  • 質問: IT業界における今日の不況について、不安、不満、問題点、打開策などについて、あなたの意見を自由にお書きください。
    • 回答: 不況の打開策とはならないと思いますが、IT業界は得てして人材育成に消極的だと思います。新人の頃から即戦力となる人材を求めるならば、学生への教育を支援していくべきです。一方、即戦力を求める割には学生の能力に期待していない企業も多いでしょう。OJTの名のもとに、応用ばかり教えても基礎は育ちません。敵と戦うことを考える前に、まずは己を磨くべきだと考えています。