CubicLouve

Spring_MTの技術ブログ

JavaのJSONObjectのgetIntとoptInt

JavaのJSONObjectのgetIntとoptInt

import org.json.JSONException;
import org.json.JSONObject;

public class HelloWorld {
  public static void main(String... args) {
    String json = "{\"screen_name\":\"katty0324\",\"age\":\"\"}";
    JSONObject jsonObject = new JSONObject(json);
    System.out.println(jsonObject.getInt("age"));                                                                               
  }
}
% javac -J-Dfile.encoding=UTF-8 -classpath . HelloWorld.java
% java HelloWorld
Exception in thread "main" org.json.JSONException: JSONObject["age"] is not an int.
    at org.json.JSONObject.getInt(JSONObject.java:543)
    at HelloWorld.main(HelloWorld.java:8)

こちらはぬるぽ

import org.json.JSONException;
import org.json.JSONObject;

public class HelloWorld {
  public static void main(String... args) {
    String json = "{\"screen_name\":\"katty0324\",\"age\":\"\"}";
    JSONObject jsonObject = new JSONObject(json);
    System.out.println(jsonObject.optInt("age"));                                                                               
  }
}
% javac -J-Dfile.encoding=UTF-8 -classpath . HelloWorld.java
% java HelloWorld
0

0返ってくる

参照

Web API The Good Partsを読んだ

APIばっかり最近作っているので、Web API The Good Partsを早速買って読んだ。

これからAPIを作ろうとしている人、現在作っている人達の机に一冊あっても良いと思う。

これまで、TLや色々なところで議論されてきたWeb APIのクライアント側とサーバー側の"お約束"が言語化されており、リファレンス本に近いと感じた。(Cache-Controlとか、、うっ急に頭が。。)

レビューとかしているときに、この本の何ページ目を参照とか書くことになると思う。

またRFC 7230の内容(2014年6月頃にリリースされたっけな)を取り込んでおり、出版の最終段階で修正していたのではないかと想像すると、涙を禁じ得ない。

知っている人に取っては当たり前の内容ばかりかもしれないが、これまでの"こうするよね〜"とされてきたAPIの"お約束"が一冊の本にまとまっているということだけでも価値のある一冊だと思う。

クライアントとサーバーのやりとりのお約束を明文化した色が強いので、サーバーの細かい実装方針(マイクロサービスとか)とかには言及していないので、その点だけ買う場合はご注意を。

これからうちのチームに配属された場合にはこの本を読むことを勧めようと思う。

macで共有ライブラリの依存関係を調べる

mysql2 gem を mysql5.6 の libmysqlclient.a と static link したい話 を読んでいて、macでも共有ライブラリの依存関係調べようとしたら、

zsh: command not found: ldd

lddの代わりにotoolコマンドを使う。

 % otool -L .rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mysql2-0.3.17/lib/mysql2/mysql2.bundle
.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mysql2-0.3.17/lib/mysql2/mysql2.bundle:
    /usr/local/lib/libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
    /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 50.0.0)
    /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 50.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)

otoolのオプションはこんな感じ。

-lとかも便利そう。

 % otool
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool [-arch arch_type] [-fahlLDtdorSTMRIHGvVcXmqQjC] [-mcpu=arg] [--version] <object file> ...
    -f print the fat headers
    -a print the archive header
    -h print the mach header
    -l print the load commands
    -L print shared libraries used
    -D print shared library id name
    -t print the text section (disassemble with -v)
    -p <routine name>  start dissassemble from routine name
    -s <segname> <sectname> print contents of section
    -d print the data section
    -o print the Objective-C segment
    -r print the relocation entries
    -S print the table of contents of a library
    -T print the table of contents of a dynamic shared library
    -M print the module table of a dynamic shared library
    -R print the reference table of a dynamic shared library
    -I print the indirect symbol table
    -H print the two-level hints table
    -G print the data in code table
    -v print verbosely (symbolically) when possible
    -V print disassembled operands symbolically
    -c print argument strings of a core file
    -X print no leading addresses or headers
    -m don't use archive(member) syntax
    -B force Thumb disassembly (ARM objects only)
    -q use llvm's disassembler (the default)
    -Q use otool(1)'s disassembler
    -mcpu=arg use `arg' as the cpu for disassembly
    -j print opcode bytes
    -C print linker optimization hints
    --version print the version of /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool

isucon4本戦に参加して惨敗してまいりました。 #isucon

1回でもいいから良い報告をしてみたいものです。

とりあえず、今は勢いで書く。

後で追記していく。

お題

今回は動画広告配信システムのチューニングでした。

いろいろやったけど

結局クライアント側のキャッシュ全然思いつかなかった。。。。

思いの丈を

サーバーとクライアントがいて初めて成り立つのであって、クライアント側のことを忘れちゃいけないよってことですよ。。。

まあ、忘れてないんだけど、意識から外れることがあったよな。。。。

つい、サーバー側だけで考えてしまっている。

まあ、リクエストをサーバーに送らないのが最強ですよね。

今回どうやって気がつくべきだったか。

tcpdumpしてheaderみておくのがいいのか。

未だに解は見つからず。。。

最期に

毎年書いているけど、はじめの一歩の鴨川会長のお言葉。

毎日の積み重ねがキサマらを弱くする!
漫然と日々をすごすなっ
四六時中ボクサーであることを自覚しろ
自分に足りないモノ、
必要なモノを常に考えて行動せよ!!

あー、今年も勉強になりました。

運営チームの皆様本当にお疲れ様でした!

lldbでrubyのデバッグ初級編

スーパールーキーに教わってたことのメモ

putsメソッドrb_f_putsを呼んでいるので、そこでbreakpoitを仕込んでbacktrace取る。

% lldb `rbenv which ruby`
(lldb) target create "/opt/boxen/rbenv/versions/2.1.2/bin/ruby"
Current executable set to '/opt/boxen/rbenv/versions/2.1.2/bin/ruby' (x86_64).
(lldb) b rb_f_puts
Breakpoint 1: where = ruby`rb_f_puts, address = 0x0000000100069f60
(lldb) r -e 'puts 1'
Process 31982 launched: '/opt/boxen/rbenv/versions/2.1.2/bin/ruby' (x86_64)
Process 31982 stopped
* thread #1: tid = 0x12faced, 0x0000000100069f60 ruby`rb_f_puts, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100069f60 ruby`rb_f_puts
ruby`rb_f_puts:
-> 0x100069f60:  pushq  %rbp
   0x100069f61:  movq   %rsp, %rbp
   0x100069f64:  pushq  %r15
   0x100069f66:  pushq  %r14
(lldb) bt
* thread #1: tid = 0x12faced, 0x0000000100069f60 ruby`rb_f_puts, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100069f60 ruby`rb_f_puts
    frame #1: 0x000000010016d07b ruby`vm_call_cfunc + 987
    frame #2: 0x000000010016c9cb ruby`vm_call_method + 843
    frame #3: 0x000000010015610c ruby`vm_exec_core + 10156
    frame #4: 0x000000010016334f ruby`vm_exec + 127
    frame #5: 0x0000000100164238 ruby`rb_iseq_eval_main + 392
    frame #6: 0x000000010003ebb4 ruby`ruby_exec_internal + 148
    frame #7: 0x000000010003eade ruby`ruby_run_node + 78
    frame #8: 0x0000000100000d5f ruby`main + 79
    frame #9: 0x00007fff8cb225fd libdyld.dylib`start + 1
    frame #10: 0x00007fff8cb225fd libdyld.dylib`start + 1
(lldb) finish
1
Process 31982 stopped
* thread #1: tid = 0x12faced, 0x000000010016d07b ruby`vm_call_cfunc + 987, queue = 'com.apple.main-thread', stop reason = step out
    frame #0: 0x000000010016d07b ruby`vm_call_cfunc + 987
ruby`vm_call_cfunc + 987:
-> 0x10016d07b:  movq   %rax, %r12
   0x10016d07e:  movq   0x20(%r13), %rax
   0x10016d082:  addq   $0x50, %rax
   0x10016d086:  cmpq   %rbx, %rax

MacOSでLD_PRELOADを実現するには

LD_PRELOAD試そうとおもったらMacでうまくいかず。。。

MacにはLD_PRELOAD自体はなく、LD_PRELOAD相当のDYLD_INSERT_LIBRARIESがあるそうなのでそれを試してみる。

元の実行ファイル(hello.c)

#include <stdio.h>
int main() {                                                                                                                                      
  puts("hello world!!");
  return 0;
}

これをコンパイルしておく。

% clang -Wall -o hello hello.c
% ./hello
hello world!!

今度は上書きするためのファイル(preload_test.c)

#include <stdio.h>
int puts(const char *str) {
  printf("preloaded\n");
  printf(str);
  putchar('\n');
}

これをコンパイルする(dynamiclibオプションつける)

% clang -Wall -o preload_test.dylib -dynamiclib preload_test.c
preload_test.c:6:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.

実行してみる。

% DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./preload_test.dylib ./hello
preloaded
hello world!!

できた。

これを足がかりに色々してみたい。