ISUCON夏期講習に参加した
ISUCON
去年のISUCON3の予選にも出たんだけど、FAILしまくってダメだった( 第三回ISUCONの予選に出たけどダメだった - 明日から本気だす )ので、今年こそ予選突破するため(?)に夏期講習に参加してみました。
会場は、LINE社のセミナールーム的な部屋でした。
入り口がめっちゃ緑色だったり窓口?がすごく綺麗でした。
お話
LINE社の採用の話とか、ISUCONについてなどのお話がありました。
次に過去問にチャレンジがあったのですが、その途中でもヒントとかテクニックの解説を聞けました。
過去問にチャレンジ
ISUCON3の予選問題に似ている感じの過去問を、その場で解くこともしました。
自分ができたこと(&スコアに反映できたっぽいこと)は、
- apacheをnginxに置き換える
- unicornのワーカ数を変える
- mysqlにindexを貼る
- Webアプリ(sinatra)の実装を修正する
- 使っていないところでSELECTを呼んでいたのを消す
- アイテム数を表示するためにCOUNTを呼んでいたのをMAX(id)に置き換える
くらいでした。
途中途中で解説があって、めちゃ面白そうな話っぽかったのですが自分の作業が中途半端だったせいで話半分にしか聞けませんでした、残念。
初期状態では1700点くらいのスコアが最終的に2500点位になったのですが、中の人は9000点超(!?)したなどを聞いてびっくりしてました。
懇親会
渋谷ヒカリエの裏らへんにあった、オサレなとこで懇親会までありました。 久しぶりにピザとか食べまくりました。
他にも、LINE社の中の方のお話を色々聞けて楽しかったです。
Effective Java
Effective Javaを読み始めたのでメモなど
項目1 コンストラクタの代わりにstaticファクトリーメソッドを検討する
普通にクラスのインスタンスを生成するならばコンストラクタを使用するけれど、コンストラクタよりもstaticファクトリーメソッドを使ったほうが良いケースがある。
staticファクトリーメソッドの利点
public class Hoge { // コンストラクタ // "Hoge"クラスなのでコンストラクタの名前はHogeになってしまう public Hoge(int i, int j, String str) { } // staticファクトリーメソッド // 好きなメソッド名を付けることができたり、同じ引数のメソッドだけど違う結果がほしい時にも便利 public static factoryMethod1(int i, int j, String str) { return XXX; } public static factoryMethod2(int i, int j, String str) { return XXX; }
staticファクトリーメソッドなら、新たなオブジェクトを生成することが必要ない。
- immutableなオブジェクトを生成したいときにも良い
- パフォーマンスが大幅に向上することも
パラメータ化された型のインスタンス生成の面倒さを低減できる。
// "<String, List<String>>"って書くのがめんどい Map<String, List<String>> map = new HashMap<String, List<String>>(); // Java 7ならダイアモンド構文がある! Map<String, List<String>> map = new HashMap<>(); // staticファクトリーメソッドを使えば、上の冗長だった文が簡潔に書ける public static <K, V> HashMap<K, V> newInstance() { return new HashMap<K, V>(); } Map<String, List<String>> map = HashMap.newInstance();
staticファクトリーメソッドの欠点
newInstance()ってのはよく見る気がするし、メソッドチェーンぽくインスタンス生成できるのは良さげだと思った。
項目2 数多くのコンストラクタパラメータに直面した時にはビルダーを検討する
- テレスコーピングコンストラクタ・パターンだと、引数の種類が多すぎると対処するのが大変。
public class Facts { private final int calories; // 必須 private final int fat; // オプション private final int sodium; // オプション // コンストラクタがパターンごとに必要になってしまう // また、引数の順序が難しい public Facts(int calories) { this(calories, 0, 0); } public Facts(int calories, int fat) { this(calories, fat, 0); } public Facts(int calories, int fat, int sodium) { this.calories = calories; this.fat = fat; this.sodium = sodium; } } // colaインスタンスの生成 Facts cola1 = new Facts(100, 50, 20); // {calories, fat, sodium} = {100, 50, 20} Facts cola2 = new Facts(100, 50); // {calories, fat, sodium} = {100, 50, 0} Facts cola3 = new Facts(100); // {calories, fat, sodium} = {100, 0, 0} ...
- Java Beansパターンだと、生成の過程で不整合な状態ができてしまうことがある。
public class Facts { private int calories = 0; private int fat = 0; private int sodium = 0; // コンストラクタは空で引数もなし public Facts() {} // Setterで処理 public void setCalories(int val) { this.calories = val; } public void setFat(int val) { this.fat = val; } public void setSodium(int val) { this.sodium = val; } } // colaインスタンスを生成し、その後Setterで状態を与える Facts cola = new Facts(); cola.setCalories(100); cola.setFat(40); ...
- ビルダーパターンで書くと
public class Facts { private final int calories; // 必須 private final int fat; // オプション private final int sodium; // オプション public static class Builder { // 必須 private final int calories; // オプションはデフォルト値で初期化しておく private int fat = 0; private int sodium = 0; // 必須パラメータはコンストラクタで代入 public Builder(int calories) { this.calories = calories; } // オプションパラメータは好きなだけ public Builder fat(int val) { this.calories = val; return this; } public Builder sodium(int val) { this.sodium = val; return this; } public Facts build() { return new Facts(this); } } private Facts(Builder builder) { this.calories = builder.calories; this.fat = builder.fat; this.sodium = builder.sodium; } } // colaインスタンスの生成 Facts cola1 = new Facts.builder(100).fat(50).sodium(20).build(); Facts cola2 = new Facts.builder(100).fat(50).build();
ビルダーパターンはいい感じだけど、記述量が結構増えてしまうので引数が多い状況に使うのが良さそう
テレスコーピングコンストラクタ・パターンやJavaBeansパターンよりはかなり安全。
Norikra meetupに行ってきた
メモ: https://gist.github.com/rkmathi/b38759a0d24a40e814fa
卒研に使えるかなーと思ったけど、ちょっと用途が違うぽい感じだった
めちゃ便利そう&気軽に使えるので使い方によっては良いきがした
Minicondaを試そうとしたが
普段、PythonをHomebrewでインストールしたpyenvで使っているのですが、ふとpyenv install -lを見てみたら色々なパッケージがありました。
$ pyenv install -l Available versions: 2.4.0 ... # ふつうのPython2系 2.7.7 3.0.1 ... # ふつうのPython3系 3.4.1 anaconda-1.4.0 ... # 数値計算ライブラリが最初から入ってるPython anaconda-1.8.0 ... miniconda-2.2.2 ... # なんだこれ? miniconda3-3.4.2 ...
どうやら、MinicondaというのはPythonで数値計算のライブラリを使うためのパッケージのようですが、Anacondaと違って、あとからライブラリを選んで入れるようでした。
http://conda.pydata.org/miniconda.html
そこでせっかくなので、試しに入れてみました。
まず、pyenvでMinicondaの最新版を入れます
$ pyenv install miniconda-3.4.2 $ pyenv global miniconda-3.4.2 $ pyenv rehash (一度シェルを開き直す) $ python --version Python 2.7.7 :: Continuum Analytics, Inc. $ conda list # packages in environment at /Users/rkmathi/.pyenv/versions/miniconda-3.4.2: # conda 3.5.5 py27_0 openssl 1.0.1h 0 pip 1.5.6 py27_0 pycosat 0.6.1 py27_0 python 2.7.7 0 pyyaml 3.11 py27_0 readline 6.2 2 requests 2.3.0 py27_0 setuptools 3.6 py27_0 sqlite 3.8.4.1 0 tk 8.5.15 0 wsgiref 0.1.2 <pip> yaml 0.1.4 1 zlib 1.2.7 1 $ conda install numpy Fetching package metadata: .. Solving package specifications: . Package plan for installation in environment /Users/rkmathi/.pyenv/versions/miniconda-3.4.2: The following packages will be downloaded: package | build ---------------------------|----------------- numpy-1.8.1 | py27_0 3.0 MB The following packages will be linked: package | build ---------------------------|----------------- numpy-1.8.1 | py27_0 hard-link Proceed ([y]/n)? yes Fetching packages ... numpy-1.8.1-py 100% |#######| Time: 0:00:46 67.81 kB/s Extracting packages ... [ COMPLETE ] |#######| 100% Linking packages ... [ COMPLETE ] |#######| 100 $ conda list # packages in environment at /Users/rkmathi/.pyenv/versions/miniconda-3.4.2: # ... numpy 1.8.1 py27_0 ...
こんなかんじで、とりあえずNumPyを入れるところまで動かしました。
次に、インストールしたパッケージを使って環境を作ります。
virtualenvwrapperみたいなかんじですが、環境を作るときの入れたいパッケージを自分で選び、足りない場合はダウンロードからしてくれます。
例として、Numpy 2.1.0とIPythonをインストールしたnumpy21
という名前の環境を作ってみます。
$ conda create -n numpy21 ipython numpy=2.1.0 Fetching package metadata: .. Solving package specifications: . Package plan for installation in environment /Users/rkmathi/.pyenv/versions/miniconda-3.4.2/envs/numpy21: The following packages will be linked: package | build ---------------------------|----------------- ipython-2.1.0 | py27_2 hard-link numpy-1.8.1 | py27_0 hard-link openssl-1.0.1h | 0 hard-link python-2.7.7 | 0 hard-link python.app-1.2 | py27_2 hard-link readline-6.2 | 2 hard-link sqlite-3.8.4.1 | 0 hard-link tk-8.5.15 | 0 hard-link zlib-1.2.7 | 1 hard-link Proceed ([y]/n)? yes Linking packages ... [ COMPLETE ] |######| 100% # # To activate this environment, use: # $ source activate numpy21 # # To deactivate this environment, use: # $ source deactivate # $ source activate numpy21
しかし、何故か自分の環境だとactivateした瞬間にシェルごと落ちました(;´Д`)
ナンデー