文字コードと向き合えるように -『プログラマのための文字コード入門』

今週のお題「2014年プライベートでやりたいこと」に乗っかって、ブログをひさびさに。

今年は本読んだらブログにアウトプットしようと思ってます。
まず一冊目、『プログラマのための文字コード入門』です。


文字化けと私

長らくシステム開発のお仕事をやっていますが、文字化けが大嫌いでした。
生理的に受けつけない、一番嫌いなレベルです。

理由はメカニズムをよく理解していないから。
そして、理解しようという気がないからです。

とはいえ、文字化けや文字コードに対して見解を求められることも増えてきており、
現在のプロジェクトでも質問攻めにあい、逃げ腰で耳塞いでいると後々火が吹きそうな予感。

意を決して文字化けと向き合おうとしました。

そのとき手にとったのがこの本です。

嫌いだったからこそ…

この本の存在自体は前から知っていました。読んで知識を充実したい思いもありました。
ですが、生理的に受けつけないのでパラパラめくって見ないふりでした。

そういう人間でしたが、読んでみるとなかなかに興味深い内容でした。

苦手分野だったため時間もかかり、睡魔にも度々襲われましたが、
読み進めるたびに発見があり充実感を得ました。

苦手意識を長年蓄積していただけあって、問題意識はたっぷり持っていました。
この本を読むための目的が人一倍あったことになります。

「文字化けのこの部分がよくわからんっ」というようなクエスチョンは明確にあり、
回答を探し求めるように読みふけました。

・JIS第三水準、第四水準ってなに?
Shift_JIS、MS932、CP932、Windows-31J って何使えばいいの?
機種依存文字ってなに?
草なぎ剛の「なぎ」って、扱いなんなの?
・波ダッシュ(〜)はDBに入れるとなんで文字化けするんだ?
Unicode は一体、1文字何バイトなのだ?
・LF、CRLF とか改行コードの違いって意識せなあかんのか?

こんな疑問たちを長年蓄積していて、断片的にググった内容で
わけもわからず都度乗り切っていたわけですが…

今となっては、胸張って回答やら仕組みを言えてしまうというスゴさ。

この本に感謝です

文字化けはまだまだ嫌いですが、少し嫌いくらいまでになりました。
おそらく文字化けについて、人並みかそれ以上はしゃべれる自信がつきました。

本を読んで、こんなにスッキリになったのは久しぶりです。

ふつうのWebアプリにGradleをしこむ

個人的にテストコードを書いたり、Gradle で自動化するのを実践しているのですが、
仕事に活かせているのは小規模で自分の裁量が大きいプロジェクトに限られています。

大規模なプロジェクトになると色々と抵抗勢力が多くて、色々と説得するのが億劫なので
こっそり Gradle を仕込んで Jenkins 動かそうと今試みています。

個人的にはコソコソ動いてておもしろいので、成果をメモしていきます。

"ふつう" な前提条件

Gradle を仕込むのは「ふつうの Eclipse プロジェクト」です。
ここで言う「ふつう」とは…

Maven ディレクトリ構成ではない

src/main/java, src/main/resource, src/main/webapp といったディレクトリ構成ではなく、
src の下に java ファイルがあったり、WebContent ディレクトリの下に WEB-INF や JSP があったりです。
Eclipse がプロジェクト新規作成時に勝手に作ってくれるディレクトリ構成ですね。

◯みんなのPCには Maven も Gradle も入ってない

そんなビルドツールなんて知りません。Eclipse の付属で付いている Ant のちょっとしたビルドが
動いているかもしれません。でも、そんなの意識したことがありません。

jar ファイルは WebContent/WEB-INF/lib にちゃんとコミットして置く必要があります。
ビルドするたびにリポジトリから最新のライブラリを取得するなんてよくわからないです。
それに、プロキシが邪魔して Gradle のプロキシ設定しないと、社外にはアクセスできないです。

◯自動化するからといってやり方が変わるのは嫌だ

Maven でビルド動かさないと jar ファイルが見つからないとか、そういうのはいけません。
Subversion からソースコードを取得したらそのまま使えるのが大事です。
build.gradle というよくわからないファイルがコミットされてるぞ?くらいで留めないとダメです。

こっそり仕込むこと

主に Gradle と Jenkins を使って、色々と自動化を仕込んでいきます。

1.War ファイルを作る  ←今ココ
2.ちょっとずつ作っていく JUnit テストコードでテストする
3.テスト環境に War ファイルをデプロイする
4.テスト環境でスモークテストを実行する

とりあえず build.gradle ファイル

apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: "WebContent/WEB-INF/lib", include: '*.jar')

    compile 'org.apache.tomcat:tomcat-servlet-api:7.0.42'
    compile 'org.apache.tomcat:tomcat-jsp-api:7.0.42'
}

project.webAppDirName = 'WebContent'

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'src'
        }
    }
}

war {
    exclude 'WEB-INF/lib/**'
    exclude 'WEB-INF/classes/**'
}

def defaultEncoding = 'UTF-8'
compileJava {
    options.encoding = defaultEncoding
}

以下、順を追って設定内容を説明していきます。

お決まりの冒頭

apply plugin: 'war'

repositories {
    mavenCentral()
}

Java の Web アプリケーションなので、War プラグインを設定します。
あと、リポジトリMaven セントラルレポジトリを設定します。
ここまではお決まりです。

jar ファイルはすでにコミットされているものを使う

dependencies {
    compile fileTree(dir: "WebContent/WEB-INF/lib", include: '*.jar')

    compile 'org.apache.tomcat:tomcat-servlet-api:7.0.42'
    compile 'org.apache.tomcat:tomcat-jsp-api:7.0.42'
} 

普通は依存関係にある jar ファイルは次のような形式で書いてリポジトリから取得するのですが、

compile 'org.springframework:spring-web:3.2.1.RELEASE'

jar ファイルは WEB-INF/lib にコミットされているものを使わないといけないので、
そのディレクトリにある jar ファイルをコンパイル時に参照するように設定します。

例外的に Tomcat のランタイムの jar ファイルをコンパイル時に参照するように設定しています。
Eclipse プロジェクトではサーバランタイムを参照するように設定します。それに対応するものです。
これを設定しておかないと、Gradle でビルドするときに HttpServletRequest などの Java EE クラスが
存在しないということでコンパイルエラーになります。
Gradle で動かす時だけ Tomcat のランタイムをレポジトリから引っ張ってくることになります。

Maven ディレクトリ構成ではないので調整する

project.webAppDirName = 'WebContent'

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'src'
        }
    }
} 

Gradle や Maven のデフォルトのままだと、

 JSP や WEB-INF は… src/main/webapp ディレクトリ
 Java ファイルは… src/main/java ディレクトリ
 Java 以外のファイルは… src/main/resources ディレクトリ

に配置しないと動かないので、次のようにディレクトリ構成を変更しています。

 JSP や WEB-INF は… WebContent ディレクトリ
 Java ファイルは… src ディレクトリ
 Java 以外のファイルは… src ディレクトリ

本当はテストコードのディレクトリ構成も調整しないといけないのですが、
今はテストコードがないので調整していません。

War ファイルを作るときの不都合を回避する

war {
    exclude 'WEB-INF/lib/**'
    exclude 'WEB-INF/classes/**'
}

「gradle war」をたたくことで、Gradle が War ファイルを作ってくれるのですが、
ディレクトリ構成をいじったりしていることもあり、作成された War ファイルの中を見ると
同じファイルが重複して梱包されてしまいます。ファイルがサイズ膨大化します。
重複を回避するおまじないです。

エンコーディングを指定する

def defaultEncoding = 'UTF-8'
compileJava {
    options.encoding = defaultEncoding
}

ほとんどお決まりのような設定です。
こちらも本当はテストコードに対する指定も必要です。

こっそり War ファイルを作成できるようになる

色々と書きましたが、build.gradle を少し調整するだけで
Gradle をインストールした環境で「gradle war」とするだけで War ファイルが作れます。

自分のPCやテスト環境に Gradle を入れることとで、こっそりと簡単に実行できます。

問題点はテストコードがなく自動テストをしていないので、作った War が正しく動くかはわからないということです。それをやるためにはテストコードを書かないといけないのですが、それはハードル高いですね。

まずは War ファイルを作れるようになったということで。
Eclipse プロジェクトの右クリック→「エクスポート」→「War ファイル」からの脱却です。

SIer では、エンジニアは評価されにくい?

うちの会社はそこそこ大きい SIer です。
そういう環境であることを前提に話を進めます。

とあるきっかけがあって、
プロジェクトマネージャより高評価を得るエンジニアになるにはどうすればいいか。
なんてことを考えています。

スーパープログラマ不要論

標準化や共通化が一定のレベルを越えると、暴れ馬なスーパープログラマが一人いるよりも
従順な低レベル作業者数人を厳密なルール下で強制労働させる方がよさそうに見えます。

大規模プロジェクトでは数こなして、進捗率上げるのが至上ですからね。

実際はそんなことはなく、問題が起こった時には役に立たない烏合の衆と化したり、
動くだけでなんの付加価値もない成果物ができあがったりします。

人を管理できる方が評価しやすい

とは言え、うまくいかなかった時のことなんて頭の片隅に置いておくのが世の常なので
一匹狼なエンジニアよりも、複数人を管理するプロジェクトマネージャの方が重要視されます。

もちろん、顧客をシャットダウンしてシステムしか見ないエンジニアは論外ですが、
顧客もシステムも見ながらすごいスキルを発揮するエンジニアもいるわけです。

そういうエンジニアって管理重視な視点で見ると、評価されにくくなります。
「結局あの人は進捗管理とかやっぱり弱いし、リーダー経験してないし…」
人事評価の場でそういう声をよく聞きます。マイナスポイントのほうが目立ちます。

「でも、あの時あの人がいなかったらダメだったでしょ。徹夜してがんばってくれたよ」
といった意見は加点対象にならないことが多いです。
エンジニアは技術で苦労して当然、家帰って技術書読むのも当然なのでしょう。

逆を言うと、技術を全く知らない管理者に苦労したりします。

そもそも違う役割なのだから

人を管理しているのがプロジェクトマネージャで、
一方で技術を管理しているのがエンジニアです。

あつかう対象が違うのだから、評価も違った見方で行わないといけないはず。
確かに人を管理するほうが一般的には難しいことは違いないですが。

でも、プロジェクトには役割がそれぞれ必要なわけで。
プロジェクトマネージャだけでも成り立たないし、エンジニアだけでも成り立たないです。

総じて最高責任者たるプロジェクトマネージャの評価が高くなるのは避けられないですが、
そうはいっても、エンジニアもその努力にうまくフォーカス当てて評価されるようにしたいです。

じゃあ、どうする?

エンジニアが自由に自らのスキルで持って価値を生み出せるようにしたい。
そして、それを評価されるようにしたいと思っています。
大きな会社には保守派が多くて大変ですが。

まずは自分の力でなんとか変えれる、小さな範囲から。
実例を積み上げる。

ポモドーロ、愚直にやってみた

ポモドーロ自体は知っていました。
少し25分測ってやってみた時期もありました。

最近、やることも山積みで帰るのも24時超え。量的に多すぎるというのも確かにあるのですが、TODOをまったく消化できないという感覚がありました。

ポモドーロ再入門

ということで『ポモドーロテクニック入門』を手に取りました。

この本の存在自体はだいぶ前から知っていたのですが、
わざわざ読むほどのこともないと、たかをくくってました。

誤認していたポモドーロ

きちんと本を読んで認識しなおしました。

「25分内でなんとかタスクを終わり切る」ためのテクニックだと思っていたのですが、
「25分間集中する」ためのテクニックであることがわかりました。

集中するので結局はタスクが終わり切るのですが、
まず第一は集中すること、でした。

これが前提をくつがえす、大きな誤認。

本を読んで、このことに気づきました。
ポモドーロはいかにして集中するための環境づくりをするかのテクニックでした。

ということで今日実践しました

Android のPomodoro アプリ
・紙
・ボールペン

今日やること、とりあえず書き出してタイマーセットしてやってみました。
結論から言うと・・・むちゃくちゃ、仕事がはかどりました。

あ〜自分はここ最近、まったく集中してなかったんだなあと痛感しました。
今日は集中し過ぎましたね。頭がいたい。

ふりかえり

工夫したこと
・目の前の事以外考えないようにするように、とりあえず走り書きメモを意識
・メールボックスを閉じておく(受信通知もOFF)
・デスクトップのファイルをお掃除
・コーヒーやジュースの補充は休憩の時だけ
・休憩の時はPC触らない、とりあえず歩く・放心する
・最後にふりかえりをした

やってみてわかったこと
・ひとつのことに集中する感覚、重要
・タスクを何とか終わらせるというのは二の次
・集中するための準備は大切
・25分集中したら、休まないとやってられない
・意外と割り込みは少なかった(おそらくメールを見なかったから)
・頭がいたい(いい意味で。集中した証拠)

失敗したこと
・今日やることの全量を書き出していなかった(エンドレスになりかけた)
・25分過ぎても延長してしまったこと数回。そのときはやっぱりダラダラした。

その他、副次的な事象
・メールが溜まるようになった(5件も溜まったことなんて最近なかった)
・メールの返信を後回しにしなくなった(早く送って忘れたくなった)
・イライラしなくなった(あれもこれもやらなきゃという感じがない)

ということで…

おかげさまで、いっぱいTODOが消化できたので、正確には消化できたという確たる感覚を得られたので、今日は早めに帰る気になりました。(とは言え22:00退社ですが)

ひさびさにブログ書くこともできました。
(このブログは2ポモドーロでした)

読書感想文 in ブログ

ブログで読書感想文を書く難しさ

読書感想文をいざ書こうとすると書けないことが多いです。
下手すれば、初めの1文を書きだすのにも多大な時間を要します。

また、書くにしても話すにしても、読んだ本の良さをうまく伝えるのは難しく、
適切な言葉が出てきません。
自分の考えや思いをアウトプットするのは非常に困難なことだということを痛感します。

ブログを書くことと論文力の関係

情報処理技術者試験には論文問題があるのですが、
ブログを書くようになってから、採点評価があがりました。

ブログを書くことと論文技術の関連性があると必ずしも言えないですが、
少なくとも論文問題を書くスピードが上がったのは確実です。

ブログは不特定多数の目にさらす文章なので、自然とセルフチェックも厳しくなります。
自分しか見ないメモや身内のメールとはまったく異なります。
きちんと意図が伝わるかという点に私は気を配っていたりします。

そういうところのつながりはあるかと。

失礼な敬語や間違った語彙が散りばめられたメール。
字面や体裁がよさそうな言葉を並べているだけのプレゼン資料。
うまく明文化するのに手間がかかりすぎるため、引き継がれないノウハウ。

文章力というのは実はビジネスという領域では重要です。
ですが、一朝一夕で成長するものではないです。

ブログを書いている理由

インプットばかりで消化不良だったのでアウトプットの場としてブログを始めました。
ブログを続けている理由は今もアウトプットの場というのが第一の目的ですが、
最近は文章力の練習の場としても意識するようになった気がします。

目的・ねらいを外さずにまとめられるか。いかにはやく書くか。

簡単そうに思えて実は難しく、うまく書けていないことが多いです。
また、時間をかけたらいいかというとそうではなく、書きだめすると結局書かなかったりします。

ブログを初めて約1年経ってみて、なんとなくブログを書くことの良さが
わかってきたかなと思います。
もっと文章力を向上させるために、今後は読書感想文なトピックも書いていこうと思っています。