JJUG CCC 2015 fallに参加しました
会社の同期に誘われ、JJUG CCCに参加してきました。
Timetable / JJUG CCC 2015 Fall(11月28日開催) | 日本Javaユーザーグループ
せっかく参加したので、メモ書き程度に参加記を残しておきます。
発表資料
既にまとめてくださっている方がいました。d.hatena.ne.jp
講演の感想
(参加中メモを取らずに聞いていたので、かなり適当です。)
CD-1 苦手克服!例外スタックトレースから読み解くバグ
立ち見が大量に出るほど人気な部屋だった。
途中から自作ツールの宣伝になっていたような気がするけど、きっと気のせい。
IntelliJの補完を巧みに使ってたのが印象的。
EF-2 How to speed up your application using JCache[通訳あり]
10年ぐらいかけて仕様策定されたぜ!
Cache使わずにMap使ってるだけだったらCache使うと良いYO!
みたいなセッション(適当)
時間配分を完全に間違えてたみたいなので、資料が上がったらちゃんと読んでみたい。
GH-3 マイクロサービスアーキテクチャ – アーキテクチャ設計と開発プロセスの歴史を背景に
この日に聞いていた中でプレゼンがとても分かりやすかった。
自分が関わっているところもマイクロサービスは意識されているなーと思った。
けど、わざと本番環境を落とすChaos Monkeyは怖すぎるw
GH-5 サーバサイドのビュー処理エンジンForneusの開発秘話
要求される仕様に合うテンプレートエンジンがない(当時見つからなかった)から作った時のお話。
Web系知識もあまりないので、そんなことできるんだと思うことばかりでした。
今回はとにかくスピード!って感じで開発されていて、何かにこだわって開発するといい物ができるのかなと思いました。
懇親会
一緒に来ていた同期と話していた。
LT大会がやってたけど、お酒が入ってるテンションからか(良い意味で)くだらない発表が多かったw
反省点はもっと色んな人と交流を持てたらよかった・・・。
参加してみて
勉強会というかこういうコミュニティに参加することは2回目ですが、モチベーションを高めることができました。
モチベーションが下がり始めたら勉強会とか参加するようにしよう。
Vim scriptのmap系コマンドの後ろにコメントは書けない
タイトルの通り。そんな仕様知らなかった・・・。
map
以下のようにmap系のコマンドを使えば、キーマッピング設定が書ける。*1
inoremap jj <ESC>
これは、インサートモード時にjjを入力するとESCキーと同様の操作(ノーマルモードに変更)をするという、よくあるキーマッピングである。
コメント
また、「"」以降はコメントとなる。 もちろん、コマンドの行末にコメントを記入することもできる。
" this is a comment. set number " show line number
mapコマンドのコメント
しかし、map系コマンドの場合コメントと認識されない仕様*2がある。
inoremap jj <ESC> " this is not comment.
このような設定をした場合、jjを入力するとESCキー、半角スペース、「"」、半角スペース、「t」「h」「i」「s」・・・の順に入力されてしまう。
結論
map系コマンドの行にはコメントを書かない。 変な挙動なまま1年間ぐらい使ってました・・・。 シンタックスハイライトされないなー・・・。と思ってた時に気付いていれば・・・。
ニコニコ動画検索APIが公開されたので触ってみた。
ニコニコ動画の公式から検索用APIが公開されてたのでPythonで関数にしてみた。
ニコニコ動画 『スナップショット検索API』 ガイド
ちなみにPythonは勉強したてなので,Pythonの練習も兼ねて。
# coding:utf-8 import urllib2 import json import sys import codecs sys.stdout = codecs.getwriter('utf_8')(sys.stdout) def nico_search(query, service=['video'], search=['title', 'description', 'tags'], join=['cmsid', 'title', 'view_counter'], issuer='nico_api'): req = urllib2.Request('http://api.search.nicovideo.jp/api/snapshot/') req.add_header('content-type', 'application/json') data = json.dumps({'query': query, 'service': service, 'search': search, 'join': join, 'issuer': issuer}) res = unicode(urllib2.urlopen(req, data).read(), 'utf-8') return res if __name__ == '__main__': res = nico_search('初音ミク') print res
{"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","type":"hits","values":[{"_rowid":0,"cmsid":"sm23720459","title":"初音ミク","view_counter":581},{"_rowid":1,"cmsid":"sm19065818","title":"初音ミク","view_counter":54},{"_rowid":2,"cmsid":"sm15309998","title":"初音ミク 綠光","view_counter":322},{"_rowid":3,"cmsid":"sm22962024","title":"初音ミク","view_counter":148},{"_rowid":4,"cmsid":"sm23739051","title":"初音ミク2","view_counter":216},{"_rowid":5,"cmsid":"sm23486084","title":"Google × 初音ミク CM","view_counter":389},{"_rowid":6,"cmsid":"sm3027541","title":"MUGEN初音ミク","view_counter":2116},{"_rowid":7,"cmsid":"sm22908770","title":"LEGO 初音ミク","view_counter":105},{"_rowid":8,"cmsid":"sm24514916","title":"初音ミク bgm1.mp4","view_counter":31},{"_rowid":9,"cmsid":"sm20491983","title":"初音ミクprojectDIVAf OP","view_counter":130}]} {"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","type":"stats","values":[{"_rowid":0,"service":"video","total":230168}]} {"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","endofstream":true,"type":"hits"} {"dqnid":"08744ec3-0b3b-4b73-b942-5c46f5351fa8","endofstream":true,"type":"stats"}
検索キーワードを指定すると検索結果(今回は動画ID・タイトル・再生数)が返ってくるだけ。
超シンプル。
まだまだオプションがあるので、弄ってみようと思う。
一応Githubにも公開しておきます。
https://github.com/otomarukanta/nicosearch
MacにVirtualBoxとVagrant入れて、CentOS7.0にDjango環境を構築した。
タイトルの通り。
Mac OSのバージョンは10.9.4
VirtualBoxとVagrantのインストール
Homebrewを使ってインストール
brew cask install virtualbox
brew cask install vagrant
バージョンは
VirtualBox:4.3.16
Vagrant:1.6.5
CentOS7.0のBoxを追加
以下のURLから使用したいBoxを選ぶ。
A list of base boxes for Vagrant - Vagrantbox.es
今回はCentOS7.0のBoxを選択。
$ vagrant box add centos70 https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box ==> box: Adding box 'centos70' (v0) for provider: box: Downloading: https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box ==> box: Successfully added box 'centos70' (v0) for 'virtual box’!
仮想マシンの作成・起動
ダウンロードしたBoxを使って仮想マシンを作成・起動してみる。 $ mkdir -p ~/Vagrant/CentOS70 $ cd ~/Vagrant/CentOS70 $ vagrant init centos70 $ vagrant up
すると以下の様なマウントできねぇよ!みたいなエラーが出てくる。
Failed to mount folders in Linux guest. This is usually because the "vboxsf" file system is not available. Please verify that the guest additions are properly installed in the guest and can work properly. The command attempted was: mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant The error output from the last command was: /sbin/mount.vboxsf: mounting failed with the error: No such device
ちょっと調べると解決方法が見つかるのでそれを実行。
vagrantでmountエラーの解決方法 - Qiita
$ vagrant ssh [vagrant@localhost ~]$ sudo /etc/init.d/vboxadd setup [vagrant@localhost ~]$ exit $ vagrant reload
無事エラーが出ずに仮想マシンの起動に成功!
Djangoの開発環境構築
まず、Pythonのバージョンを確認。
[vagrant@localhost ~]$ python -V Python 2.7.5
次にpipをインストール。
[vagrant@localhost ~]$ wget http://peak.telecommunity.com/dist/ez_setup.py [vagrant@localhost ~]$ python ez_setup.py Setuptools version 0.6c11 or greater has been installed. (Run "ez_setup.py -U setuptools" to reinstall or upgrade.) # 既に入ってたorz [vagrant@localhost ~]$ sudo easy_install pip
そしてDjangoをインストールと確認。
[vagrant@localhost ~]$ sudo pip install django [vagrant@localhost ~]$ python Python 2.7.5 (default, Jun 17 2014, 18:11:42) [GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> print django.get_version() 1.7 >>> exit()
Djangoのプロジェクトを作成・サーバー起動
[vagrant@localhost ~]$ mkdir django [vagrant@localhost ~]$ cd django/ [vagrant@localhost django]$ django-admin.py startproject helloworld [vagrant@localhost django]$ cd helloworld/ [vagrant@localhost helloworld]$ python manage.py migrate [vagrant@localhost helloworld]$ python manage.py runserver
無事成功したが、仮想マシン上でのサーバー起動なため、単純にWebブラウザからアクセスできない。
Vagrantfileを編集することで、指定したポートへのアクセス(ホストOS)をゲストOSの指定ポートに転送してくれるみたい。
Vagrant で Python(Django) 開発環境を準備する - Qiita
# config.vm.network "forwarded_port", guest: 80, host: 8080 # 以下に変更 config.vm.network "forwarded_port", guest: 8000, host: 8080
仮想マシンを再起動、もう一度Djangoプロジェクトのサーバーを起動。
$ vagrant reload $ vagrant ssh [vagrant@localhost ~]$ cd django/helloworld/ [vagrant@localhost helloworld]$ python manage.py runserver 0.0.0.0:8000
Webブラウザからlocalhost:8080にアクセス・・・できない。
悩むこと1日。あ、ポート開放してないじゃんと気づく。
CentOS7.0からはfirewallコマンドというのを使って設定するらしい。
[vagrant@localhost helloworld]$ sudo firewall-cmd --permanent --add-port=8000/tcp [vagrant@localhost helloworld]$ sudo systemctl restart firewalld.service
そしてもう一度Webブラウザからlocalhost:8080にアクセスするとIt Works!の文字が!
文字を文字コードに変換する
文字を文字コード(今回はSJIS)に変換する必要があった。
例えば’A’を’8260’など。
以下のようなWEBサービスでは結構でてくるのに、処理の中身自体がなかなか見つからない。
文字コード変換 WEBアプリケーション、フリーCGI配布 ---ahref.org
が、ついに今日!
以下のページを見つけた!!
あの文字のバイト列は何になるんだっけ 各文字コードの16進数表記を求める(PHP/JavaScript/Perl/Ruby/Python) - INASOFT 管理人のふたこと
まさに探していた情報!!
結構前から探してたけど、少し前に公開されていたみたい。感謝。
というわけで、Pythonのソースを参考に以下のコードを作成。
# -*- coding: utf-8 -*- import binascii def char2sjis(c): return binascii.hexlify(c.encode('sjis')).upper() if __name__ == '__main__': c = u'A' print char2sjis(c)
とてもシンプル。
Apache + PHP + MySQL on MacBookPro
MacBookPro、OS X 10.9.4上にWEB開発環境を構築する。
以下のサイトを参考(そのまんま)にApache+PHP+MySQLの環境を構築。
いちいちsudo〜ってコマンドでファイルを編集したくなかったので、
DocumentRootを変更した。
すると403 Forbiddonに。
[Mac] apacheでローカルサーバーを構築する方法 | Memo on the Web
一箇所だけじゃなく、もうひとつ変更しなければならなかった。
/etc/apache2/httpd.confの以下2つを任意のパスに変更することで正しく動いた。
DocumentRoot "/Library/WebServer/Documents"
typeidの罠
クラスの型を調べるtypeid演算子というのがある。
でも、実際に使ってみると正しい結果を出してくれなかった。
結果として、継承元のクラスに仮想関数がなかったらダメということ。
ダメな例
#include <iostream> #include <typeinfo> class A{ }; class B : public A { }; int main(int argc, char **argv) { A *aa = new A(); A *ab = new B(); B *bb = new B(); std::cout << typeid(A).name() << std::endl; std::cout << typeid(B).name() << std::endl; std::cout << typeid(*aa).name() << std::endl; std::cout << typeid(*ab).name() << std::endl; std::cout << typeid(*bb).name() << std::endl; return 0; }
1A 1B 1A 1A // ここはBになって欲しい 1B
クラスAに仮想関数を持たせると
#include <iostream> #include <typeinfo> class A{ virtual void hoge() {}↲ }; class B : public A { }; int main(int argc, char **argv) { A *aa = new A(); A *ab = new B(); B *bb = new B(); std::cout << typeid(A).name() << std::endl; std::cout << typeid(B).name() << std::endl; std::cout << typeid(*aa).name() << std::endl; std::cout << typeid(*ab).name() << std::endl; std::cout << typeid(*bb).name() << std::endl; return 0; }
1A 1B 1A 1B // Bになった! 1B