- Sentry フロントエンドエラー可視化
- New Relic アプリ監視ツール
Java8 ラムダ式でよく利用する関数型インターフェース
関数型インターフェースとは?
- 単一メソッドを持つインターフェース群
- ラムダ 式で利用するのに都合がいい
- SE8からjava.util.functionパッケージに追加された
ラムダ式を引数として取る場合に、関数型インターフェースを指定して受け取る。
ラムダ式の種類毎に用意された入れ物が関数型インターフェースとも言える。
// 例として、filter()は関数型インターフェースを引数に取る numbersList.stream().filter((i) -> { return i > 0; })
関数型インターフェースとして使用頻度の高いFuction、Consumer、Predicateを見ていく。
Function<T,R>
Function<T,R>のTはメソッドの引数の型、Rは戻り値の型を指定する。
メソッドはR apply(T)を使って、定義した処理に引数を渡して、結果を返却する。
// Functionにラムダ 式(メソッドオブジェクトのようなもの)を代入 Function<Interger, Integer> calcPlusOne = (i) -> { return i + 1 }; // calcPlusOneを使ってみる Integer result = calcPlusOne.apply(1); // result = 2
Function<T,R>を引数に取るStreamAPIのメソッドmap
ListString impNum = numbersList.stream().filter((i) -> { return i >= 0; }) .map((i) -> { return "*" + i + "*"; }) .forEach((s) -> { System.out.print(s + " "); }); // *2* *0* *8*
Function<T,R>は、引数が1つで処理結果を返却したい場合のラムダ式に用いる。
Consumer
Consumer
メソッドはvoid accept(T)を使って、定義した処理に引数を渡して、結果を返却する。
Consumer<String> greeting = (name) -> { System.out.println(name + "さん、おはようございます。"); }; greeting.accept("太郎"); // 太郎さん、おはようございます。
Consumerを引数に取るStreamAPIのメソッドforEach
numbersList.stream().forEach((i) -> { System.out.print(i + " "); }); // Eachは要素の数だけ繰り返す。
Consumer
Predicate
Predicate
Predicate<T> checkBigNum = (num) -> { return num > 10000} boolean result = checkBigNum(10); // result = false
Predicateを引数に取るStreamAPIのメソッドfilter
// numbersListに-1 と2と8あり numbersList.stream().filter((i) -> { return i > 0; }) // 負の数を除外 .forEach((i) -> { System.out.print(i + " "); }); // 2 8
Predicate
Pythonの負荷テストツール Locust
Pythonで負荷テストコードを記載するLocustについて記載します。
特徴
- シナリオを Python で記述
- 分散&スケーラブル
- Web ベース管理画面
- 高いカスタマイズ性
本家サイト
- Github:GitHub - ktanakaj/locust-example: Example scripts for Locust
- Github/example:locust/examples at master · locustio/locust · GitHub
- ドキュメント:Locust Documentation — Locust 2.1.0 documentation
動かしてみる
テストケース
from locust import HttpUser, TaskSet, task, between, constant class UserBehavior(TaskSet): @task(1) def profile(self): self.client.get("/sample", verify=False) # パスにはプロトコルやホストは記載しない class WebsiteUser(HttpUser): tasks = {UserBehavior:1} min_wait = 5000 #タスクの実行間隔はmin_waitとmax_waitの間のランダム値となる max_wait = 15000 # 上書き時に記述。デフォルトは min_wait=500, max_wait=1500 単位はミリ秒
起動
locust # 以下の省略版 # locust -f ./locustfile.py
http://localhost:8089でWeb UIにアクセス可能
参考サイト
MacOS Python3系インストール
Pythonバージョン管理ツールのpyenvを入れて、3系のPythonをインストール&適用させていきます。
pyenvをインストール
brew install pyenv
pyenvの設定(シェルがzshの場合)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc echo 'eval "$(pyenv init -)"' >> ~/.zshrc source ~/.zshrc
Pythonインストール
pyenv install --list pyenv install 3.9.6
インストール済pythonの確認
pyenv versions * system (set by /Users/UserName/.pyenv/version) 3.9.6
ローカルへのpythonの適用
pyenv global 3.9.6 python3 --version Python 3.9.2 python3 hello.py #Pythonファイルの実行
JSON用のgrepみたいなjqコマンド
JSONを便利に編集できるjqコマンドできる基礎的なことを書いておきます。
マニュアル、参考URL
公式マニュアルをみておくと幸せになれる。
jq Manual (development version)
ここに書いていることでメモしておきたいことを書いていきます。
jq コマンドを使う日常のご紹介 - Qiita
コマンド使い方
.
がルート{}
を表します。
整形
% echo '{"items":[{"item_id":1,"name":"たろう"},{"item_id":2,"name":"はなこ"}]}' \ | jq . { "items": [ { "item_id": 1, "name": "たろう" }, { "item_id": 2, "name": "はなこ" } ] }
列取得
% echo '{"items":[{"item_id":1,"name":"たろう"},{"item_id":2,"name":"はなこ"}]}' | jq '.items[]..name' "たろう" "はなこ" # ダブルコートを消すには -r をつける % echo '{"items":[{"item_id":1,"name":"たろう"},{"item_id":2,"name":"はなこ"}]}' \ [14:48:38] | jq -r '.items[].name' たろう はなこ
フィルタ(パイプみたいなもの)
'.items[]'までの結果を.nameへ渡す。
% echo '{"items":[{"item_id":1,"name":"たろう"},{"item_id":2,"name":"はなこ"}]}' \ [14:48:44] | jq -r '.items[] | .name' たろう はなこ
パイプの後で編集
項目の順序やプロパティー名を変更、配列にしたりなど
% echo '{"items":[{"item_id":1,"name":"たろう"},{"item_id":2,"name":"はなこ"}]}' \ [14:50:27] | jq -r '.items[] | {name2: .name, item_id2: .item_id}' { "name2": "たろう", "item_id2": 1 } { "name2": "はなこ", "item_id2": 2 }
他にもいろいろありそうだけど、一旦ここまで。
Kotlin 正規表現
下記の例を貼らせて頂きました。
Kotlinの正規表現の使い方 | 寝室コンピューティング
// a,b,cのうちいずれかにマッチ val regex = Regex(pattern = "[abc]") // Raw Stringはエスケープ不要 """\d""" // 普通の文字列だとエスケープが必要 "\\d" // 文字列に数字が含まれているかチェックする val target = "1 apple. 2 bananas." val regex = Regex("""\d""") val isMatched = regex.containsMatchIn(target) print(isMatched) val match = regex.find(target) print(match?.value) // 結果:1 val matches = regex.findAll(target) matches?.forEach { match -> print("${match.value} ") } // 結果:1 2 val target = "090-1111-2222" val regex = Regex("""(\d+)-(\d+)-(\d+)""") val match = regex.find(target) match?.groups?.forEach { group -> println("${group?.value}") } /* 以下が格納されている group[0]:090-1111-2222 group[1]:090 group[2]:1111 group[3]:2222 */
Mockito 基礎文法
Mockitoでパッとわからなかった書き方について書いていきます。
戻り値なしメソッド
何も返さないメソッドが指定インスタンスと引数のときにMock化されます
Mockito.doNothing().when(モックインスタンス).メソッド(任意の引数);
privateメソッド、staticメソッド
MockitoではMock化できない。実現したい場合、PowerMockを使う
モックオブジェクトの検証(verify)
- @mock @spyどちらのオブジェクトに対しても使用可能
- 呼ばれた回数の検証ができる
指定回数呼ばれているかtimes
sample1.method1(10); sample1.method1(20); sample1.method1(20); verify(sample1,times(2)).method1(20); // OK verify(sample1,times(3)).method1(20); // エラー
指定回数呼ばれているかatLeastOnce atLeast atMost never
verify(sample1,atLeastOnce()).method1(0); // 最後に呼ばれたメソッドと引数が一致で正常 verify(sample1, atLeast(2)).method1(20); // 2回以上でOK verify(sample1, atMost(2)).method1(20); // 2回以下でOK verify(sample1,never()).method1(20); // 0回で正常 (times(0))と等価