株式会社はてなに入社しました
マネージャとしても 2 年目になりました。 今年もよろしくお願いします。
株式会社はてなに入社しました
マネージャとしても 2 年目になりました。 今年もよろしくお願いします。
大江戸Ruby会議08でぺんさんが最後に再生していた頭のおかしい (褒め言葉) Quine。
僕の発表の最後に紹介したごろごろしたQuineコードです #oedo08 pic.twitter.com/mkp8TaVaVt
— ぺん! (@tompng) February 11, 2020
コードはこちら
https://gist.github.com/tompng/45d93b3386b5986a94b9c3c8beecba69
まず見慣れた (毎年 Ruby 会議に参加しているうちになぜか見慣れてしまった) アスキーアートプログラミング構文が使われている。
eval((c=%{ ... }).split*'')
詳しくは あなたの知らない超絶技巧プログラミングの世界 の第 2 章を参照だけど、%{}
の中がプログラムを好きな形に整形したもの。スペースや改行を取り除いた上で、セミコロンで改行してあげると人間が読める程度に復元できる。
c=(w*26+';eval((c=%{'+c+"}).split*'')").split$/
の辺りが Quine。
eval c=
を文字列として再構成して、自身を埋め込んでいる。
0.upto(90) {|tm| ... puts(...) sleep(0.05) }
sleep
を入れながら 91 回 puts
している。つまりこのプログラム全体は 91 枚のパラパラ漫画。
tm
(タイマーかな) を固定すると任意のコマを描画できる。
m = 96 ... cn = (1..m).map { [0] * m } ... puts( (0..47).map {|i| m.times.map {|j| l, j = [cn[2*i+1][j], cn[2*i][j]] %['".:Y,L#])[3*l+j] } * '' } * $/ )
96 * 96 の 2 次元配列を変数 cn
(多分キャンバス) に入れてあり、puts
している。
(0..47).map {|i| ... }
は最後に $/
つまり "\n"
で *
(Array#join
) しているので 行 、m.times.map {|j| ... }
が空文字で join
しているので 列 。
各画素は
%['".:Y,L#])[3*l+j]
で、3*l+j
を出力してみると
000000000000000000000034100000011100000000000000000000000000000000000000000000000000000000000000 000000000000000000000041000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000440000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000033343000000000000000000000000000000000000000000000000000000000000000000000000000 000000000003010000000011330000000000000000000000000000000000000000000000000000000000000000000000 000000000000668888888866014300000000000000000000000000000000000000000000000000000000000000000000 000000001062200008888888660143000000000000000000000000000000000000000000000000000000000000000000 000000000066660008888888806014300000000000000000000000000000000000000000000000000000000000000000 000000400888888600288882008004400000000000000000000000000000000000000000000000000000000000000000 000000008888888800000000008004400000000000000000000000000000000000000000000000000000000000000000 000000302888888200688660688004400000000000000000000000000000000000000000000000000000000000000000 000000100888800008888888882034400000000000000000000000000000000000000000000000000000000000000000 000000010028860008888888820344100000000000000000000000000000000000000000000000000000000000000000 000000001300286602288822003441000000000000000000000000000000000000000000000000000000000000000000 000000000013300002200033444100000000000000000000000000000000000000000000000000000000000000000000 000000000000111444444441100000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000001430000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000440000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000001430000003333333000000000000000000000000000000000000000000000000000000 000000000000000000000000000143034111111111443300000000000000000000000000000000000000000000000000 000000000000000000000000000034100666686666001443000000000000000000000000000000000000000000000000 000000000000000000000000000310062222288888860014300000000000000000000000000000000000000000000000 000000000000000000000000003106200000088888888000430000000000000000000000000000000000000000000000 000000000000000000000000004006888860028888880080040000000000000000000000000000000000000000000000 000000000000000000000000000088888888000222200080040000000000000000000000000000000000000000000000 000000000000000000000000000088888882000660000880040000000000000000000000334444444433000000000000 000000000000000000000000004028888220068888868880040000000000000000000344441100000011143000000000 000000000000000000000000001302888000688888888200400000000000000000004441006688888866001430000000 000000000000000000000000000030028600088888882034144330000000000000044400622222288888866013000003 000000000000000000000000000001300222066222003410000114433300000000444002060000088888880600334441 000000000000000000000000000000001033333333110000000000001114443333440068888860028888820060110000 000000000000000000000000000000000000000000000000000000000000000111440088888880000020000680000000 000000000000000000000000000000000000000000000000000000000000000000440088888880006666006880000000 000000000000000000000000000000000000000000000000000000000000000000143028882200688888888800100000 000000000000000000000000000000000000000000000000000000000000000000014302886000888888888000000000 000000000000000000000000000000000000000000000000000000000000000000000130028600088888820010000000 000000000000000000000000000000000000000000000000000000000000000000000001330022000020001000000000 000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
のようになっていて、例えば 0
を に置換することで各画素を出力している。目を細めてみるとこれだけでも絵が見えますねw
':.
を使って 1 画素を更に上下に分割していたり (そのために行の倍のサイズのキャンバスがある)、#
と :
を使い分けることで色の濃さ(質感)を表現していたりする。
x = 1.62 * t + 2 y = -1.44 * t - 2 z = 10 - 7 * t - 4.1 * [tm - 6, 0].max / 9
の辺りがカメラ。
x = 0, y = 0, z = 3
とかに固定すると、その場で画像がクルクル回る。
rn
が数式を 3D 描画しているところ?で、ピタゴラスの定理的なものが見えるねフンフンナルホドとか言ってみるけどまだ理解していない。
rn = ->(x, y, z, th) { xx = n + m * x / z yy = n + m * y / z rr = 144 / z r1 = 2**2i r2 = E**th.i tr = ->(x, y, z) { x, y = ((x + y.i) * r1).rect x, z = ((x + z.i) * r2).rect [*((x + y.i) / r1).rect, z] } ([0, xx - rr].max.ceil..[m - 1, xx + rr].min).each {|ix| ([0, yy - rr].max.ceil..[m - 1, yy + rr].min).each {|iy| vx, vy, vz = tr[ix / n - 1, iy / n - 1, -2] cx, cy, cz = tr[-x, -y, z] vv = vx * vx + vy * vy + vz * vz * 3 vc = vx * cx + vy * cy + vz * cz * 3 h = 0.3 d = vc * vc - vv * (cx**2 + cy**2 + cz**2 * 3 - 1 - h * h * 3) d < 0 && next x2 = cx - vx * s = (h / vz).abs + cz / vz y2 = cy - vy * s x2**2 + y2**2 > 1 && next ... } } }
lambda が一つのオブジェクトになっていて、例えば雷は tn
で
tn = ->(i,j) { a = 1 - j/52 b = j>40 ? 0 : 1 j = n - j/2.0 (j/2 - a*16) < i && i < (j - b*16) }
これを描画するとこうなる。
,####################### ####################### ,###################### ###################### ,##################### ##################### ,#################### #################### ,################### ################### ,################## ################## ,################# ################# ,################ ################ ,############### ############### ,############## ############## ,#############,,,,,,,,,,,,,,,, ############################# ,############################ ############################ ,########################### ########################### ,########## ########## ,######### ######### ,######## ######## ,####### ####### ,###### ###### ,##### ##### ,#### #### ,### ### ,## ## ,# # ,
gt
が雷門。
gt = ->(x, y) { y -= 0.2 i = n + x * 168 j = 24 + y * 84 # 屋根 next(x * (-y)**0.5 * 16 % 1 < 0.5 ? 1 : 2) if y < -0.4 && y > -0.9 - x**6 && y > -0.4 / x**2 # 梁 next(x.abs * 2.6 % 1 > 0.6 || y > -0.35 || x.abs < 0.1 ? 2 : 0) if y >= -0.4 && y < -0.32 - x**4 / 10 # 提灯の中の「雷門」って文字列 next(2) if (0 <= j && j < n && 0 < i && (c[j][i] || w) != w) # 提灯 next(1) if 2 * x**4 + y**4 < 0.01 # 風神雷神 x = (x.abs - 0.5).abs y < -0.4 || y > 0.55 || x > 0.2 ? 0 : x > 0.12 || y > 0.47 || (y - 0.2) % 0.5 < 0.1 ? y > 0.45 && x > 0.12 ? 2 : 1 : 2 * x * x + y * y < 0.01 + y % 0.05 / 5 ? 1 : 0 }
雷門は特に提灯の中の「雷門」文字部分の実装が意味分かんなくて、
next(2) if (0 <= j && j < n && 0 < i && (c[j][i] || w) != w)
なんと c
つまりこのプログラム自身の文字列を参照している。
AA になっているので提灯の中に「雷門」が出現するのだよね。プログラムを左寄せにすると提灯の中も左に寄る。
::Y#L::##::##''""'''""''""''""'''""''""''""'''""''""''""''"""''""''""''"""::##::##::##Y L::##::##::Y##::##::##L::##::##::###::##::##:::##::##::##Y::##::##::L##::##::##Y:L##::##' #::##::Y##::##::Y#L::##::##L::##::##:::##::##:::##::##::L##::##::L##::##::##Y::##::##Y::##' "::##L::##::##L::##::###::##::Y##::##:::##::##:::##::##:::##::##Y::##::##Y::##::L##::##::L##' "::Y#L::##::Y##::##L::##::Y##::##L::##::###::##:::##::###::##::L##::##Y::##::L##::##Y::##::L#Y "::Y##::##L::##::Y##::Y##::##L::##::Y##::###::##:::##::###::##Y::##:::##::###::##Y::##::L##::##Y ::Y##::Y##::##L::##L::##:::##::Y##::###::###::##:::##:::##::###::###::##Y::##:::##::L##::L##::## :Y##::Y##::Y##::###::###::###::##L::##L::##:::##:::##:::##:::##:::##::L##::L##::L##::L##::##Y::# Y##::Y##::Y##::Y##::Y##:::##:::##:::##:::##:::##:::##:::##Y::##Y::##Y::##Y::##Y::##Y::##Y::##Y:: ##::Y##::Y##:::##L::##L::###::###::Y##:::##:::##:::##Y::###::###::L##::L##:::##Y::##Y::##Y::L##: L::Y##::Y##L::##L::###::Y##:::##L::###::###:::##:::###::###:::##:::##Y::###::L##:::##Y::##Y::L## ::###::Y##L::###::Y##:::##L::###:::##L::###:::##:::###::L##:::###::L##:::##Y::###::L##Y::###::L# :##L::Y##L::###::Y##L::###:::##L::###:::###:::##:::###:::##Y::###:::###::L##:::###::L##Y::L##::: ##L::Y##:::###::Y##L::Y##L::###:::###:::###::Y##:::###:::###:::##Y::L##Y::###:::###::L##Y::L##Y: L::Y##L::Y##L::Y##L::Y##L::Y##L::Y##L::Y##:::###:::###:::###:::###:::###:::###:::###:::###:::##Y ::Y##L::Y##L::Y##L:::###:::###:::###:::###:::###:::###Y::L###:::###:::###:::###:::###:::L##Y::L# Y##L:::###L::Y##L::Y###:::###:::Y###:::###:::###::::###:::###:::###Y::L###:::###:::L##Y::L##Y::: ######## ########## ############# ########### ####### ,,######"""""""""""""""##########"""""""""#############""""""""###########"""""""""""""""######, ::::: ,,,,,,,,,,,LLLLLL,,,,,,,,,,,,,LLLLLLLLLLLLL,,,,,,,,,,,,,LLLLL,,,,,,,,,,,, ::::: :::::::::::::::::::::::::: '':::YYYY::::::::::::::::'' :::::::::::::::::::::::::: :::::::::::::::::::::::::: ####:::::::::::::::::::::::::::::' :::::::::::::::::::::::::: :::::::::::::::::::::::::: ##":::::::::::::::::::::::::::::::' :::::::::::::::::::::::::: :::::...............:::::: ####YYYYYYYYYY::::::::::::::::::::: :::::................::::: ::::: :::::: ####LL::::::::::::::::::::::::::::: ::::: ::::: ::::: :::::: ####YYYYYYYYYYYYYYYYYYYYYY:::::::::: ::::: ::::: ::::: '':::::'' :::::: ###########LLLLL:::::::::::::::::::: ::::: '::::::'' ::::: ::::: ':::::::' :::::: ###LLLL::::::::::::::::::::::::::::: ::::: '':::::::' ::::: ::::: .:::::::::. :::::: ##LLLLL::::::::::::::::::::::::::::: ::::: .::::::::::. ::::: ::::: ':::::::::::' :::::: #YYYYYYY:::::::::::::::::::::::::::: ::::: '::::::::::: ::::: ::::: ':::::::::: :::::: ####LLLLL::::::::::::::::::::::::::: ::::: ::::::::::' ::::: ::::: ..::::::::. :::::: ###Y:::::::::::::::::::::::::::::::: ::::: ..::::::::.. ::::: ::::: ::::::::: :::::: ########LLLLL::::::::::::::::::::::: ::::: ::::::::' ::::: ::::: ......... :::::: ########LLLLLLLLLLLLLLLLLLLLLLLLLLLL,,LLLLL,,,,,........ ::::: ::::: :::::: ##LLLLLLL::::::::::::::::::::::::::: ::::: ::::: ::::: :::::: ####LLLLLLLLLLLL::::::::::::::::::: ::::: ::::: :::::''''''''''''''':::::: ####LLLLLLLLLLLLLLLLL:::::::::::::: :::::''''''''''''''''::::: :::::::::::::::::::::::::: #######:::::::::::::::::::::::::::. :::::::::::::::::::::::::: :::::::::::::::::::::::::: ##########LLL::::::::::::::::::::. :::::::::::::::::::::::::: :::::::::::::::::::::::::: ,,,, .::::::::::::::::::::::::.. :::::::::::::::::::::::::: ::::: :::::: ................. ::::: ::::: ::::: :::::: ::::: ::::: ::::: :::::: ::::: ::::: ::::: :::::: ::::: ::::: ::::: :::::: ::::: ::::: #####'''''''''''''''###### #####''''''''''''''''##### #####:::::::::::::::###### #####::::::::::::::::##### #####:::::::::::::::###### #####::::::::::::::::#####
他のオブジェクトも全部数式で表現されている辺りも十二分に凄いんだけど、その凄さが霞んでしまうぐらいビックリした。
いやー、意味分かんなかった。
頑張って読んだらそれなりに理解はできるんだけど、こんなオシャレにカメラを動かせるセンスはまったく無いなー。
劇場で観た奴。
ちょうど 24 回行っていて、月 2 回ぐらい観てるんだなってのが分かる。
マレフィセントもアナ雪もターミネーターもスターウォーズも観なかったので、後半は失速したなー。シティーハンターもルパン三世も行けてない……。
全部 TOHO シネマズ 二条で観ている。徒歩圏内だし、最悪タクれば 5 分後に着けるのがめちゃくちゃ便利。
HELLO WORLD は観た直後に外に出たら聖地 (伏見稲荷から二条駅まで戻ってきて先生に捕まるところ) が目の前にあって、ずっと世界に没入してる感じで体験がめちゃくちゃ良かった。
買った順。
こうして見返すと衝動買いが多いことが分かる。
机周りが一通り揃った (モニタ、椅子、キーボード、マウス) ので、来年は IYH することは減るはず、きっと、多分。実際 HHKB は買わずに耐えているわけだし。
このエントリは はてなエンジニア Advent Calendar 2019 の 18 日目のエントリです。
前日は id:ikesyo さんによる 2019年のSwiftモック事情 でした。
今日の話。DB 負荷を継続的に計測していきたいのです。
そんなときに Percona Toolkit って良いライブラリがあるので、これを使っていきましょう。
SQL を分析するときは以下のようなことを考えます。
それぞれ見ていきましょう。
色々眺めたいので一旦 tcpdump を使います。
流れるクエリだけじゃなくて response も全部採取しているので、秒で GB 単位のデータが溜まっていくことに注意してください。
# pcap データをファイルに保存する $ sudo /usr/sbin/tcpdump -i any port 3306 -G 60 -w /tmp/tcpdump_%Y%m%d_%H%M%S.pcap
# 再生する $ /usr/sbin/tcpdump -r /tmp/tcpdump_20191218_000000.pcap -n -nn -tttt -x -q
この取得した pcap から、流れている SQL を取り出したいんですが、Percona Toolkit に TcpdumpParser
と MySQLProtocolParser
っていうイイやつがあります。
名前を見るとイメージ沸くかな。これらを繋ぐといい感じに流れたクエリを取り出すことができます。
use strict; use warnings; use utf8; use English qw(OS_ERROR); use lib '/path/to/percona-toolkit/lib'; use Data::Dumper; $Data::Dumper::Sortkeys = 1; use TcpdumpParser; use ProtocolParser; use MySQLProtocolParser; my $parser = new TcpdumpParser(); my $protocol = new MySQLProtocolParser(); my $queries = []; my $file = 'tcpdump_20191218_000000.txt'; sub _read { my ( $fh ) = @_; return <$fh>; } eval { open my $fh, "<", $file or die "Cannot open $file: $OS_ERROR"; my $parser_args = { next_event => sub { return _read($fh); }, tell => sub { return tell($fh); }, fh => $fh, }; while ( my $p = $parser->parse_event(%$parser_args) ) { my $e = $protocol->parse_event(%$parser_args, event => $p); push @$queries, $e if $e; } close $fh; }; print Dumper $queries;
こんな感じ。
$VAR1 = [ { No_good_index_used => 'No', No_index_used => 'No', Query_time => '0.000126', Rows_affected => 0, Thread_id => 4294967299, Warning_count => 0, arg => 'SELECT `users`.* FROM `users` WHERE `users`.`id` = 1', bytes => 261, cmd => 'Query', db => undef, host => '127.0.0.1', ip => '127.0.0.1', port => '58430', pos_in_log => 130658, ts => '191218 23:46:08.915939', user => undef }, ...
ところでレスポンスに NO_GOOD_INDEX_USED
とか NO_INDEX_USED
とかってフラグあったんですね。10 年以上ずっと MySQL 使ってきたけど知らなかった……。
SQL を取り出すと、
SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
のような SQL 文字列が取得できたけど、id = 1
の部分は同一視して集計したいですよね。
これまた Percona Toolkit に QueryRewriter
っていうイイやつがあります。
この fingerprint
メソッドが、よくできた normalize 処理なので、いただきます。
use QueryParser; use QueryRewriter; my $queries = ...; my $qp = new QueryParser(); my $qr = new QueryRewriter(QueryParser => $qp); print Dumper [ map { $qr->fingerprint($_->{arg}) } @$queries ];
これを通すと
$VAR1 = [ 'select `users`.* from `users` where `users`.`id` = ?', 'select `users`.* from `users` where `users`.`id` in(?+)', ...
のように normalize されたクエリが取得できます。
自分でこの正規表現書けるかというとまったく自信無いので、枯れてるライブラリは最高ですね。
normalize して、クエリごとに集計可能になったので、グルーピングして集計処理をします。
これまた Percona Toolkit に EventAggregator
っていうイイやつがあります。
あ、event ってのは、最初に Parser から取り出していた、1 クエリを表現する HashRef のことですね。
使い方はこんな感じ?
use EventAggregator; my $ea = new EventAggregator( groupby => 'fingerprint', worst => 'Query_time', attributes => { Query_time => [qw(Query_time)], }, ); for my $event (@$queries) { # fingerprint を埋めて $event->{fingerprint} = $qr->fingerprint($event->{arg}); # 集計処理に渡す $ea->aggregate($event); } # 集計結果を取得 print Dumper $ea->results;
ログ貼ると長いので省略するけど
{ classes => { fingerprint => { 集計結果 }, fingerprint => { 集計結果 }, ... }, globals => { ... }, samples => { fingerprint => { event }, fingerprint => { event }, ... }, }
のような hash が返ってきます。
classes は
{ 'select `users`.* from `users` where `users`.`id` = ?' => { Query_time => { all => { 100 => 2, 102 => 2, 98 => 1 }, cnt => 5, max => '0.000143', min => '0.000116', sum => '0.000657' } }, 'select `users`.* from `users` where `users`.`id` in(?+)' => { Query_time => { all => { 111 => 1, 94 => 1, 96 => 1 }, cnt => 3, max => '0.000221', min => '0.000096', sum => '0.000424' } }, ...
のように、Query_time を集計したもの。cnt, sum だけじゃなくて分布も眺めることができます。
samples は worst
で渡した集計軸で、一番遅かったクエリの event です。
集計軸を自分で設定できるので、Query_time
以外でも色んな方向から眺めて分析できそうですね。
normalize した結果はおそらく 数百〜2000 ぐらいに収まると思う。これを片っ端から EXPLAIN して、悪い SQL じゃないかを確かめたい。
これまた Percona Toolkit に QueryReportFormatter
、JSONReportFormatter
っていうイイやつがあります。
JSONReportFormatter
は QueryReportFormatter
の子クラスで、出力が JSON になるよう override したものですね。
先ほど作った EventAggregator のオブジェクトと、EXPLAIN を投げる先の DB Handler を渡すと、片っ端から投げまくってくれます。
my $config = { dsn => 'dbi:mysql:dbname=DATABASE_NAME;host=127.0.0.1', user => 'root', pass => 'pass', }; my $dbh = DBI->connect(map { $config->{$_} } qw(dsn user pass)); my $qrf = QueryReportFormatter->new( dbh => $dbh, ... ); $qrf->print_reports( ea => $ea, ... );
コードを見ると分かるんですが、要は文字列結合で EXPLAIN $query
としているだけです。サブクエリがある場合は安易に EXPLAIN すると死ぬ可能性があるのでスキップされます。なるほど賢い!
JSON が取れるので、もちろん Mackerel に投げて、アラートやグラフを作っていきたい、ですよねぇ。
ここまでで、クエリごとの実行回数や実行時間、一番遅いクエリ等をそれぞれ取得し、更に全クエリについて EXPLAIN 結果も取得することができました。実はこれが pt-query-digest でやってることです。
なんで自前でやってきたかと言うと、一番欲しかった全自動 EXPLAIN 結果が --output json
だとなーんか動かなくてですね、この記事はデバッグしている途中ってヤツです。
ドキュメント には
json output was introduced in 2.2.1 and is still in development, so the data structure may change in future versions.
とあります。なので JSON 出力に含める実装がまだ無い気がしています。(たぶん)
著名な便利ツールも中身は普通の Perl なので、こうして読み解いて&コントリビュートしていきたいね、というお話でした。
明日は id:Pasta-K さんです。
2019-04-01 に「チーフエンジニア」という肩書きを手に入れてしまった。
はてなのエンジニア組織にはチーフエンジニアという役割のエンジニアがいて、評価や採用、その他大小諸々の施策を通じて、技術部門全体の生産性と幸福度を向上させるのがその仕事です。
前職でも新卒採用、中途採用のお手伝いはしていたのだけれど、今は主業務の一つとして担当しているので、僕がどこを見ているのか、というのを書きとめておこう。
チラ見しています。
「通勤片道1時間ぐらいかかりそうだけど大丈夫かなぁ?」とか「趣味がルービックキューブじゃん! はてなの speedcubing 部と戦わせたろ」とかを見ています。
まぁまぁ見ています。
プロジェクトで使った技術、特にアーキテクチャについてを一番見ていると思います。次にプロジェクトの人数や、その中でどんな役割を担ったのか。
具体的に何故この技術を選択したのかとか、プロジェクトで困って解決したこと、解決できなかったことが書いてあるとすごくポイント高くなります。
技術スタックの近さも見ますが、そもそも社内で polyglot な選択をしているので (必要に応じて言語を使い分けてきたら自然とこうなった) やってきた言語そのものよりも、時代の変化とともに生きてきたっぽさを見ています。
はてなに応募される方は持ってる確率高いですね。めちゃくちゃ見ています。
普段リポジトリを見るときと同じ感じだと思う。
どんなプロダクトを作っているのかを知っておくと会話が弾むので、直近でコミットしてそうな数リポジトリ見てます。
サーバサイドっぽい話題が多いね。僕のバックグラウンドによるものです。
一人につき 30 分〜1 時間半ぐらいですねー。だいたい 30 分だと準備不足で会話しんどい。
いやー、書いてみて感じたけど、自分じゃまったく出来てないことを要求してますね。でも転職考えているならポートフォリオ整備するのを頑張りそうとも思う。
数ヶ月おきに一念発起して "Write Code Every Day" とか毎週ブログを書くとかをしばらく続けると、こういう筋力が戻ってくると思います。やっていこー