ABC064 C - Colorful Leaderboard
今日の問題
今日の言語
所要時間
2時間
2018年の抱負
2017年はこのブログ放置しすぎたので、2018年は何かやります。
一年半ほど職業プログラマとしてphpをガリガリ書いてきて、設計思想とかメモリ効率のいい実装とか、色々知識はついていると自負しているんだけれども、それを全くアウトプットしてないなぁと。
業務に関わる話なのでそのまま書けるわけでもないというのもあるけれど、自宅で全くプログラミングしなくなったのも要因の一つかなぁと。
流石にエンジニアとして死んでるよなぁ、まずいよなぁ、と思ってはいるものの2017年は結局行動しないで終わってしまった……
ので、直近の行動しますよ宣言をここに書いておきます。
1.データベーススペシャリスト試験受けます
2.競プロ始めます
デスペは春試験の合格を目指して頑張ります。
競プロは、1日1問とかのスローペースな感じで毎日PCを開いてコードを書く習慣をつけられたらいいなぁ、と思っています。
[php]phpの文字列比較時に自動型変換されているのを知らなくてハマった話
違う文字列なのに一致する...?
phpは型の制約が緩い分、意図しないところで勝手に型変換されていたりして困っちゃうことが時々あります。
例えば、文字列の比較を==で行うと、以下のような驚きの結果に。
$ echo "5seq" == 5; // true $ echo "3.0" == "3"; // true
これは、==で整数値と文字列を比較する際、文字列を内部処理でint型にキャストしてしまっていることが原因です。
どうすればいいのか?
文字列の比較の際には===を使うことで、明示的にstringでの比較を行うことができます。
$ echo "5seq" === 5; // false $ echo "3.0" === 3; // false
また、数字での比較を明確に行いたいならば、is_numeric()メソッドで文字列が数字であることを保証するという方法が取れます。
formから受け取ったユーザ入力を扱う場合などは、面倒ですが比較の前にこの処理をはさんでおくと確実です。
$str = "5sec"; if(is_numeric($str)) { // ここでfalseになる if($str == 数字) { ... } }
あるいは、扱う文字列が明確に数字である場合などは、あらかじめ明示的にキャストしてしまうという手もあります。
$str = (int)"3min"; if($str == 3) { // true ... }
型が緩いと便利ではありますが、コードを書く際はしっかりと意識しないといけませんね。
お名前vps(kvm)上のCentOS7にシリアルコンソールでssh接続する方法
接続できない...
vpsサーバのネットワークが不調になった時とか、ssh接続できなくなった状況だといつも管理画面でブラウザ上からコンソールにアクセスしていた。
ただこのブラウザ上のコンソール、コピペができなかったりしてすごく使い勝手が悪い。
できればブラウザからじゃなくて、ターミナルから操作したい。
そこで、シリアルコンソール接続でターミナルからssh接続する方法があるらしいのでやってみた。
なんだ意外と簡単に設定できるじゃん、と思ったら、
$ssh hogehoge Last login: Sat Jul 16 22:48:18 2016 from 106.161.167.199 [Enter `^Ec?' for help]
ここで操作不能になった。ログインに遷移しない...
しかもC-cが効かなくてプロセスも落とせない...
設定が簡単とか、そんなうまい話はなかったのだ。
いざ、解決の旅へ
説明通りやっているのに、なぜログインできないのか。
調べてみると、どうもサーバ側でシリアルコンソール接続の設定をしないとダメらしい。
いろいろやってみた結果、このサイトの方法で解決できた。
まず、以下のコマンドで設定ファイルを編集して、新規作成する仮想端末ttyS1とserialの対応を行う。
編集したのは以下の4行。
$ vi /etc/default/grub ~ GRUB_TERMINAL_OUTPUT="serial console" GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,9600 console=ttyS1,9600" ~ GRUB_TERMINAL="console serial" GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"
そして反映。
$ /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
次にgettyの設定を行う。
この辺りの処理は調べていくとsystemdがどうとかと書いてあったのだが、よくわからなかったので後で勉強することにして、まずは無心にコマンドを叩く。
雛形をコピって、ログインシェル振り分けるところにシンボリックリンク貼って、デーモンにサービス追加して、最後に自動起動設定してる。多分。
$cp /lib/systemd/system/serial-getty@.service /etc/systemd/system/serial-getty@ttyS1.service $ ln -s /etc/systemd/system/serial-getty@ttyS1.service /etc/systemd/system/getty.target.wants/ $ systemctl daemon-reload $ systemctl start serial-getty@ttyS1.service $ systemctl enable serial-getty@ttyS1.service
ここまで出来たら、最後に以下のファイルを編集して、ttyS1の存在を教えてあげる。
このsecurettyはrootでログインできる端末のリストらしい。
$ vi /etc/securetty ~ ttyS1 ~
これで設定は完了。
$ shutdown -r now
サーバを一度再起動して、ログインを試みる。
$ ssh hogehoge Last login: Sun Jul 17 00:52:35 2016 from 106.161.167.199 [Enter `^Ec?' for help] CentOS Linux 7 (Core) Kernel 3.10.0-327.22.2.el7.x86_64 on an x86_64 yukineko login:
できた!!
こんな面倒な設定するだなんて、公式のどこにも書いてなかったよ...
新たなる問題
今度はシリアルコンソール接続を終了できなくなってしまった...誰か助けて...
gitで追跡ファイルの大文字小文字を区別する
大文字小文字区別
gitはデフォルトだと大文字小文字の区別をしない設定になっているらしい。
$ git config --list ~~ $ core.ignorecase=true ~~
ignorecaseをfalseに設定すると区別してくれるようになる。
# 大文字小文字を区別する場合 $ git config core.ignorecase false
これで変更できた。
$ git confiig --list ~~ core.ignorecase=false ~~
そもそも、大文字小文字でファイルを分けることなんて滅多にないんだけれども。
久しぶりにサーバにログインしようとしたらsshできなかった時の話
経緯
お名前.comに借りたサーバを4か月ほど放置してたんだが、久々になんかやろうと思ってsshしてみたら接続できなくなっていた。
かまってあげないから拗ねちゃったのか?
試行錯誤
とりあえずpingしてみる。
$ ping yukineko.work PING yukineko.work (133.130.66.130): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 Request timeout for icmp_seq 2 --- yukineko.work ping statistics --- 4 packets transmitted, 0 packets received, 100.0% packet loss
Request Timeoutが発生した。ネットワークに問題があるらしい。
サーバの中で調査
仕方ないので管理画面のコンソールからサーバに入って、サーバ内部でもpingしてみる。
$ ping google.com connect: Network is unreachable
今度はnetwork is unreachableとエラーが出た。
え、サーバの外に出れない...
まさかnetworkが息をしてないのか?
$ nmcli device DEVICE TYPE STATE CONNECTION eth0 ethernet disconnected eth0 lo loopback unmanaged --
案の定eth0デバイスが死んでいた。
お前いつの間に死んだんだ。
eth0はなぜ死んだ?
ところで、ネットワーク設定が勝手に切れるはずはないので、何が起こったのかちょっと調べてみたので忘備録。
まずはサーバの起動日時を調べてみる。
$ uptime 23:13:57 up 25 days, 19:39, 2 users, load average: 0.07, 0.03, 0.05
あれ、なんか25日前にサーバが起動してる...
もしかして、メンテナンスか何かで一度サーバが再起動されたのか?
案の定、eth0の設定ファイルを開いてみたらONBOOTがnoになっていた。
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet NAME=eth0 ~~ ONBOOT=no ~~
これが原因か......
ONBOOTの値をyesに変更しておけば、次は大丈夫なはず!
インデックスと複合インデックスのうまい使い方
dbの検索高速化
大量のデータがあるデータベースには、select文の実行速度を上げるためにインデックスを作成することが多い。
最近データベースを勉強していて、複合インデックスなるものの存在を初めて知ったので詳しく調べてみることにした。
以下のサイトがとてもわかりやすくまとめてあったと思う。
このサイトはもう一歩くらい踏み込んでいて、読んでいて面白かった。