The King's Museum

ソフトウェアエンジニアのブログ。

【Effective Java 3rd Edition】Chapter 1: Introduction

この本は Java の言語とライブラリを効果的に利用するための手引きについて書かれています。 全部で 90 の項目があり、それぞれで一つのルールが示されています。

この本では最近の Java の特徴についてもカバーしています。

Feature Items Release
Lambdas Item 42-44 Java 8
Streams Item 45-48 Java 8
Optionals Item 55 Java 8
Default methods in interfaces Item 21 Java 8
try-with-resources Item 9 Java 7
@SafeVarargs Item 32 Java 7
Modules Item 15 Java 9

この本の規則は、明瞭性(clarity)と簡潔性(simplicity)という原則から導かれています。あらゆる再利用可能なコンポーネント(モジュール)は、その挙動でモジュールの利用者を驚かせてはいけませんし、その規模は小さくあるべきです。また、コードはコピーされないで再利用されるべきです。

エラーはなるべく早い段階で検知できるようにし、実行時ではなく、コンパイラ段階で検知できるように努めるべきです。

この本で提示される規則は常に守らなければならないわけではないですが、まずは規則を学び、ときにそれを破るという姿勢をもつべきです(守破離)。

明瞭で、正しく、再利用可能で、強固で、柔軟性があるようにコードを書いていれば、たいていの場合、必要なパフォーマンスが得られます。 そうしておけばパフォーマンスが本当に必要になったとき、簡単にそれを得ることができるでしょう。

Java の構成要素

Java には4種類の型があります。

  • interfaces(annotations を含む)
  • classes(enums を含む)
  • arrays
  • primitives

最初の3種類は reference types として知られています。また、class instance と array は objects と呼ばれます。

クラスは次の要素を持っています。

  • fields
  • methods
  • member classes
  • member interfaces

メソッドシグネチャは次の要素で構成されます。

  • name
  • the types of its formal parameter

メソッドの戻り値の型が含まれないことに注意してください。

用語

この本では『Java 言語仕様』とは異なる用語の使い方をしているケースがあります。 ただし、大抵のケースはそのまま理解できるものでしょう。

例えば、この本では「サブクラス化(subclassing)」を「継承(inheritance)」と書く場合があります。

API

この本において API とは次の要素を示しています。

  • classes
  • interfaces
  • constructors
  • members
  • serialized forms

プログラマはこれらを通して各種モジュールアクセスするためです。 これらの要素が Javadoc で標準出力されるのは、偶然ではなく意図的にそうなっています。

API を利用するプログラマをユーザーと呼び、API を利用するクラスをクライアントと呼びます。

Java 9 では module system が導入されています。 ライブラリが module system を使っている場合、module で宣言されたパッケージが公開 API となります。

感想

Effective Java 3rd を読むついでに、第二版(日本語)向けに書いた記事をアップデートしてみることにした。

最初に Effective Java の記事書いたのもう2年半前。 読み返してみるとやっぱり間違ってるところあるし、こういう記事書いておいてなんだけど、本気の人はちゃんと本で読んだ方がいいですよ・・・(そして僕に間違いを教えてください)

Effective Java

Effective Java

独自ドメイン化しました

この度、ブログを独自ドメイン化しました。

http://www.thekingsmuseum.info

はてなブログもプロになったので広告やキーワードリンクなどを消しました。 (もしかしたらいつの間にか Google AdSense が入っていたりするかもしれません)

ついでにこっそりアイコンやニックネームを僕自身のものに変更しました :-)

今後ともよろしくお願いします。

第226回 TOEIC の結果

去年の12月に受験した TOEIC の結果が返ってきた。

Listening Reading Total
425 445 870

あわよくば 900 超えないかなーなんて思ってたけどそんなことはなかった。 パート2の問題文がまともに頭に入ってこなくて(理由は不明)、かなり適当にマークしてしまった割にはとれたかな。

これまでの TOEIC のスコア推移は次の通り。

受験日 Listening Reading Total
2017/12(今回) 425 445 870
2017/3 430 415 845
2016/3 350 400 750

細切れにしか勉強時間が確保できないから、勉強してる実感はあまりないけど、スコアはちゃんと伸びてきてる。 毎日、少しずつ、ってのは勉強の王道ですね(特に言語学習では)。

前回、845 取ったときは「これぜったい上振れでしょ…」と思ってたけど、今回は 850 を超えたわけで「TOEIC 850 〜」くらいの位置にはいるんだよね。 でも、これくらいのスコアが取れるようになってきて、スコア 900 レベルだと自分のイメージしていた「英語ができる姿」にぜんぜん届かないことが分かってきた。

2年前英語を勉強し始めた頃は「TOEIC は最終的に 900 超が目標かな〜」なんて思ってたが…。

数日前、「暴かれる王国 サウジアラビア」を字幕無しの英語音声で見たけど、

  • 完璧に意味が理解できた(文をリピート出来る): 0.5 割
  • なんとなく意味が理解できた(単語などから推測):2.5 割
  • 言ったことは耳に入った(気がする)が、意味が分からなかった: 3割
  • 何を言ってるのかまったく分からなかった: 4割

って感じで、ゴールの遠さにちょっと絶望した。

でもまあ、ポジティブな面を見れば、Reading に関してはかなりレベルアップした。そこらへんの Developer Guide 程度の文書なら苦労なくスラスラと読めるようになったし。ちょっと砕けたブログとかエッセーだと途端にすらすら読めなくなっちゃうけど…。

Towards over 950

ということもあって、900 点を目標にしていると自分のイメージするゴールに全然到達しないので、まずは目標再設定して 950 点を今年の目標にした。

一般的には Listening のスコアが高くなる傾向があるみたいだけど、自分は感覚的にもスコア的にも Reading の方が明らかに得意。Reading のスコアが高い人の方がスコアが伸びやすいと書いてある記事を目にしたので頑張れば今年中の 950 も夢じゃないかも?とハードルを高めにしてみた。

本当は今までやってきたこととか、今年やろうと思ってる英語ネタを書き連ねようと思ったけど、長くなったので一旦これで終わりにして時間があったらまた書きます。

Gauche の勉強を再開。

2 年前くらいに Gauche を勉強したいなーと思ったんだけど、いろいろあって途中でやめてしまってたのを再開した。

hjm333.hatenablog.com

Scheme は SICP を Streams くらいまではやったので、簡単なプログラミングクイズみたいなのは解けたりするけど、普段使いできるレベルじゃない感じ。

目標は、

  • 普段のちょっとしたスクリプトを Gauche で書けるようになる。

という実務的なところと、

  • Lambda 式は、「レキシカルな環境を保持した手続き」(クロージャ)へと評価される
  • 手続き呼び出しは継続を伴った引数つき goto である

と本に書かれていた意味を理解できるようになる、という興味的なところかな。 まあ、現時点でもひとつ目はなんとなく理解できるけど。

理由

言語を勉強する時って「Hoge を勉強する理由」みたいな話になりがちだけど、Scheme に関しては「単純に興味があるから」くらいしか理由はない。

ここ数年はキャリアに効きそうなことを重視して勉強していたけど、単純に興味あることに少しは時間を費やしてもいいかなーと思ったのもある。 プロゲーマーのウメハラが「最近、なんとなく昔使ってたキャラをメインに使い始めたら、なんとなく人生が楽しくなってきたんですよね。昔、ゲーム始めた頃に持ってた感覚というか、そーゆーのが戻ってきた。」みたいなこと言ってたのに少し影響を受けた。

別に俺は昔 Scheme 使ってたわけじゃないけど、学生の頃に Lisp ってできるハッカーが使いこなしてるイメージがあっていつか使いこなしたいなーと思って。自分の興味あることを勉強する単純な楽しさみたいなものがここにある気がする。

キーバインド

あと Emacs の Scheme 用のキーバインドをちゃんと使いながらコード書こうとしてるんだけど、ぜんぜんうまくできないのがそれはそれで結構楽しい。 身体と頭が一致しない感じは子供の頃にキーボードの配置覚えた頃を思い出させる。外側の S 式に行こうとして、キーを押したら内側の S 式いっちゃったり。四苦八苦。

でも、頑張って練習してると昨日よりちょっとうまくカーソル動かせたりするとこれが嬉しかったりするんだよなー。

2歳半になる息子が、毎日できないことにもがきながらもどんどん成長している姿を見て、歳をとってもそういう姿勢は持っておきたいなーと感じた。

Effective Java 3rd Edition

Effective Java の 3rd Edition がついに発売するようだ。

Effective Java (3rd Edition)

Effective Java (3rd Edition)

ここからなら EPUB で買えそう。(そうすれば Kindle で読める)

www.informit.com

また解説記事書こうかな。。。

2018年1月21日追記

Effective Java 3rd Edition のまとめを書き始めました。

www.thekingsmuseum.info

ISUCON 7 で予選敗退した

ISUCON というプログラミングコンテストに参加し予選敗退した(100位近辺でした)。

isucon.net

準備

予選の一ヶ月くらい前に、会社の同僚から「今度 ISUCON に参加しません?」という話があって、会社のメンバー三人で参加することにした。

準備として、

  • Go を読み書きできるように Go Tour をやった
  • 2~3日使って ISUCON 6 の予選を一人で解いてみた
  • 同僚と ISUCON 6 の予選を議論した
  • 当日のサーバーセットアップの準備(これは僕じゃなくて同僚がやったのだけど)

あたりをやった。

予選問題をやった感想としては、プログラムとかサーバー構成はかなり簡素だなぁと思った。 デフォルト実装はかなり荒い感じ。 だからこそ、高速化する余地あるということなんだろうけど。

ただ、競技時間8時間という時間制限はなかなかシビアだなぁと思った。

当日

予選は初日に参加。奥さんに子供の世話を頼んで、朝から会社に行った

気合い入れて 9:00 に会社に行ったら開始時間延期になって 12:00 開始の予定と言われ、暇を持て余してしまった。結局、さらに遅れて最終的に始まったのは 13:10 くらいかな。 (二日目も遅れたのはさすがに…)

競技開始直後は、3 台あるサーバーの設定を同僚にまかせて、コードを見つつ高速化ポイントを探す。

お題の Web アプリにブラウザからアクセスしてみるとアイコン画像のロードが明らかに遅い。 MySQL に画像データ入っていて毎回クエリで取り出してるようだ。それは遅いわ。

データをファイルにエクスポートし Nginx で裁くように変更。 ついでにサーバー設定も見直して 50000 点くらいになった。 ここで3時間くらい経過だったかな。

この時、ファイル名はデータの sha1 だからアイコン変更があってもキャッシュ破棄しなくていいですねーとかって話は出てたんだけど、実はうまく 304 が返ってなかったようだ。これをちゃんと 304 を返せるようになってれば高いスコアが出たらしい(検証してないから分からんけど

この後の次の一手がなかなか決まらなくて時間を浪費してしまった。 結局、「グローバルなキャッシュが欲しいよね」という話になって、急遽触ったことのない Redis を導入することに(サーバーが1台なら concurrent-map とか使うだけだけどね)。 「まぁ、Get と Set と Delete さえやっとけば大丈夫でしょ」みたいなノリでがりがり実装開始。

結局、導入したけどバグ取りに追われて気がつけば残り時間わずか。 残り10分くらいになって諦めかけたていたところ、奇跡的にバグの原因を見つける。

「これはまさか奇跡の逆転勝利ってやつかな?」と脳内で盛り上がったが、ベンチマークしてみたらスコアが下がって 40000 点くらいで FINISH でした。

よかったこと

目標は予選突破だったから「結果は出ませんでした」なんだけど、いくつかポジティブな面もあったかな。

「バグでスコア 0 点でした〜」ではなかったし、画像ファイルをエクスポートするところまでの流れは良かったと思う。

特に触ったことない Redis を導入するって決断ができたのも個人的にはよかった。 こういう思い切ったチャレンジを本番でやって、一応導入まで持っていけたっていうのは結構満足している。

こういったチャレンジがきっといつか身を結ぶのかなーなんて思ったり。

わるかったこと

二手目の Redis 導入が大した根拠なく進めてしまったのはよくなかった。

プロファイルをちゃんと見たり、スコアの計算方法を見直したり、やるべきことは沢山あった。 プロファイル用の Go ライブラリも調べてはいたけれど、今回のデフォルト実装で使ってたフレームワークと合わなくて導入を諦めてしまった。 もう少し時間を使ってでも導入するべきだったな。

スコアに反映されないのに無意味に /fetch を高速化してしまったりしたのは典型的なダメパターンなのでかなり反省した。

最後の方はさすがに疲れてしまって明らかに頭が働いてない感じがあった。 いい仕事をするためには疲労は大敵だなーというのは改めて感じた。体力やエネルギーはうまく使わないと…。

あと、開始時間のズレとかで一人参加できなくなってしまって二人だけでやるのはちょっと辛かった面があったかな。

おわりに

結局、技術的なことぜんぜん書いてないが Technical な面はちゃんと書かれたブログが他にたくさんありますからね・・・。

とりあえず、ちゃんと 304 が返ってるかはきちんと確認しようね、っていうのは大事だなと思いました。

45年間で東京23区の若年層人口が半減して、高齢者人口は3倍になったという話

IT と全然関係ない話。

たまーに「このニュースのこの数字は覚えておきたいなー」と思うことがあって、そういう時どうしようかなーと思ってたけど、ささっとブログに書いておくことにした(ブログ更新頻度維持のためにも)。

今回はこのニュース。

www.nli-research.co.jp

まとめると、

  1. 1970 年と比較して、2015 年における東京都区部の 15~29 歳の人口は 52.3% 減少
  2. 同じ条件で 65 歳以上の人口は 322.1% 増加
  3. 2016 年の東京都区部の人口増加のうち 33% は外国人。(20~24歳 の増加分に限っていえば 51.5% が外国人)

という話。

1 番目も 2 番目もそれなりにインパクトあるなぁ、と思ってたけど、3 番目は特に印象深い感じ。

確かに都内のコンビニやファストフード店のバイトの人ってほとんど外国人だもんね。

(c) The King's Museum