2018-09-16
rsyslogはなにかおかしい気がする
おそらく、rsyslogは何かおかしい。
短時間に大量にログを書き込み続けると、CPU 100%になってシステムを巻き込んでクラッシュさせるような気がする。
これまで、3回ほど経験しました。
googleすると似たようなことを書いている人が何人かいる。
https://www.google.co.jp/search?q=rsyslog+bug+cpu
もちろん、少数のログならば全く問題ない。
大量に書き込み続けなければこれも問題ない。
このバグを引き起こすには、大量のログを長期に渡って書き込み続ける必要があるようだ。
大量のログを書き込み続けると、CPU 100%になってシステムをクラッシュさせるloggerとはいったい・・・
これはloggerではなくただの時限爆弾だろう。
大量にログを出力するときは、rsyslogを使わないほうがいい。
rsyslogの設定でオフにしましょう。
そして、rsyslogではなく、自分で出力しましょう。
ゆとりのある優しいログだけを出力させるようにしましょう。
rsyslogに大量のログを書かせるとシステムが死にます。多分。
2018-07-31
プログラムで大切なことは読むべきコードを少なくすること。ただそれだけだ。
オブジェクト思考とか手続き型とか、関数型とかの議論はまったく無価値だ。
こういう議論をしているお前らは、どうやら、プログラムで大切なことを理解していないのだろう。
const性も、オブジェクトも、ライブラリや部品の再利用、グローバル変数の禁止も、継承を避けることも、巨大な関数を避けることも、それはたった一つのことをやるためにあるといってもいい。
それは、読むべきコードを少なくすることだ。
コードを読むのはとにかく疲れる。
だから読むべきコードを少なくしないといけない。
コードがたくさんあると、どこにバグがあるのか、探すのが大変だ。
新しい機能を実装するべき場所を探すのが大変だし、
何を変更したときに他を間違えて、他を壊さないかのチェックも大変だ。
お前らは、printfを知っていますか?
画面に文字を表示する関数だ。
では、この関数がどのように実装されているか知っていますか?
まあ知らないだろう。俺様も知らない。
知る必要がないからだ。
仮に、この関数の内部に100万行のソースコードがあったとしても、我々はそれを読む必要はない。
printfの仕様を知っていれば、実装を読む必要がないのだ。
これで、100万行のソースコードはたった1行のコードになった。
100万行のコードがあったとしても、ブラックボックス化して無視することができる。
これがとても重要なことなのだ。
const性があれば、その機能はデータを読み込むだけで破壊しない。
よって、その関数を読んだとしてもデータが壊れない。
だから、仮に、そのデータがおかしな状態になってデバッグするときにも、その関数の先の実装を読む必要がない。
C++のconstメソッドやstaticメソッドの場合は、クラスの状態を変えないことを言語が保証してくれる。
だから、仮にクラスの状態が何か変になったとしても、そのメソッドがクラスの状態を壊さないことわけだから、そのメソッドの実装を見る必要がない。
ライブラリや部品の再利用についても同じだ。
動作実績があり、枯れているライブラリの場合、何か変な事象が起きたとしても、そのライブラリの内部まで追いかける必要性が低い。
たいていは、自分が書いたライブラリを呼び出す手順に問題があるということになるわけだ。
(これが不安定なライブラリだと、内部まで追跡しないといけず、時間と体力を消耗してしまう)
グローバル変数の禁止も同様だ。
いつどこで変更されるかわからない変数を追跡するのはとてつもなく時間がかかる。
だから禁止されるのだ。
また、オブジェクト化して、変更されるスコープをより限定することで、読むべきソースコードの範囲を狭くすることができる。
継承を避けるのも同様だ。
なぜなら、継承はクラスの足し算だからだ。
巨大なクラスになってしまうと、メンバ変数はグローバル変数の性質をより強く持ってしまう。
だから、グローバル変数の禁止と同じ理由で禁止される。
(似たようなものでsingletonをできるだけ避けるというのもあるだろう。)
巨大な関数を避けることも同様だ。
巨大な関数になってしまうと、どこで何をやっているのか追跡するのが大変だからだ。
ソースコードをひたすら読まないといけない。
テストについても、一部については同様のことが言える。
テストされて動作が保証されているコードは、枯れているライブラリと同じく内部を読む必要がないのだ。
契約による設計については語るまでもないだろう。
契約に従っていることが保証されれば、内部を読む必要がないのだ。
よって、すべてのことは、「読むべきコードを少なくする」ことのために存在する。
ここまで理解できれば、どういうコードが最良なのかわかるはずだ。
それは、読むべきコードができるだけ少なくなるように書かれたコードだ。
部品は独立しており、十分にテストされ枯れていて、いちいち内部の実装を確認しなくてもいいコードだ。
逆にどういうコードが最悪なのかも明白だ。
それは、読むべきコードが多いひたすら多いコードだ。
ドリフのコントみたいに、こちらのドアをパーンと閉めたら向こう側のドアが連動して開くみたいに、複雑に依存して全部読まないと意味がさっぱり分からないコードだ。
コードを書くときは、それは読むべき内容を増やさないだろうか?と疑問を持ちながらコードを書けばいい。
そうすれば多少はマシなソースコードが書けるだろう。
関数型でも読むべき内容が多い最悪なコードな書くことができるし、手続き型でも読むべき内容が少ない良いコードを書くことができる。
しょせんは、読むべき内容を少なくするための方法論の一つにすぎない。
どちらがいいかを議論するのは時間の無駄だ。
そんなのを議論している暇があれば、お前らのクソコードから読むべき部分を少なくする努力でもしてください。
2018-07-26
プログラムの書きすぎでキーボードが壊れることに定評があるDynabookのキーボードを交換した
キーボード交換完了。
プログラムの書きすぎでキーボードが壊れることに定評があるDynabookのキーボードを交換した。
さすがに年に2回もキーボードが壊れるとは思っていなかった。
即日修理の東芝PC工房がなくなるということで、今回は自分でやってみたよ。
とても面倒だった。
キーボードを分解工具で剥がしただけでは、ダメ。
キーボードとママンボードとの接合部が裏にあるので、分解しないといけない。
後ろカバーを開けて、バッテリーを外して、作業スペースを作ってから、
キーボードロックピンを外して、
その後で、キーボードを取り外し、
新しいのに交換して、再度接合する。
問題は、キーボードの接合部は2つあること。
メインの接合部がかなりシビアで、ちゃんとロックしないと一部のキーが入力できないという謎現象が発生すること。
なぜかRキーだけが入力できなくて、3回ぐらい開け締めしたよ。
また、後ろカバーを固定するネジも、足裏の隠しネジがあるし、とても面倒だったよ。
2018-05-11
C#の例外メッセージの書き方はクソだ
C#の例外メッセージの書き方はクソだ。
あの例外メッセージの書き方は、例外の悪い書き方でしかない。
例えばこんなのだ。
System.NullReferenceException Object reference not set to an instance of an object.
このどこが悪いのか?
それは、理由の情報が書いてないことだ。
NullReferenceException ぬるぽが起きたらしいね。
なるほど、オブジェクトがnullだったらしい。
Nullだったということはわかる。
そうだね。nullらしいね。それじゃあ修正しよう。
では、どのオブジェクトがNULLだったのかい?
・・・・
・・・・・・・・
わかりません。
まったくわかりません。
ふさげるなっ!!
デバッグビルドだとIDEが場所で止まってくれるし、情報も吐き出される。
しかし、このダメな例外メッセージの書き方で問題になるのは、リリースビルドのときだ。
スタックトレースには、pdbがないと行番号は出力されないし、あってもなぜか出力されないこともある。
(世界は広いのでそういう変な環境もあるらしい)
よって、私たちが得られる情報は、直前に実行されていた関数内のどこかのオブジェクトがnullだったということだけだ。
どこだよそれは。
そうだね。確かに消えて出せない。でも、変数の型ならだせるだろう?
どの型が問題を起こしたのか?これだけでも候補を絞り込むことができる。
なんでこんな簡単なことをやらないの?
他にもダメなのがいっぱいある。
これを作った奴らはおかしい。
System.ArgumentOutOfRangeException Index was out of range. System.Runtime.InteropServices.ExternalException A generic error occurred in GDI .
どれもこれも理由が明記されていない。
範囲外アクセスしたのはわかる。でもそれはどの型のオブジェクトで、何番目にアクセスしたから範囲外なのかといった基本的な情報が欠落している。
これはダメな例外メッセージの典型例だ。
意味が分からない例外メッセージはないと同じだ。 throw new ArgumentOutOfRangeException("fuck you"); と書いているのとほぼ同じだ。
いったいMSの開発者は何を考えていたんだ。
これを書いたMSの開発者は後で私のオフィスに来るように。
もし、このクソ仕様を受け入れるならば、関数をできるだけ小さい単位に細分化する必要がある。
そんな面倒なことはしてられないけど。
C#のネイティヴの例外は、起きたことはわかるんだけど、誰がなぜ起こしたのかわからない。
ダメな例外メッセージの書き方そのものだ。
C#の例外メッセージの書き方を真似しなければ、いいプログラムが書けるだろう。
C++だと黒魔術を利用して、例外ハンドラーそのものに割り込んで、もっとましな例外メッセージを追加したり、情報を多く取れるだろう。
しかし、C#の世界ではそれは不可能だ。ランタイムライブラリに割り込むことは不可能だろう。たぶん。
もし、もっとましな方法があるなら教えてほしい。
いったいどうやるのがベストプラクティスなんだ。
2018-03-09
死後の世界は存在するのか?[思考実験]
死後の世界は存在するのか?
死後の世界は、いろいろな宗教において、大切なテーマになっている。
今回はこれについて考えてみよう。
死後の世界は存在するのか?
俺様は、存在しないと思う。
理由は以下の通り。
例えば、生き物は死ねばあの世に行くと仮定する。
ウイルスも死ねばあの世に行くんだろうか?
行くとすれば、インフルエンザウイルスや、エボラウイルス、エイズウイルスなどの強烈なウイルスや、
あの世は恐ろしいウイルスまみれということになるだろう。
害虫とかもあの世に行くんだろうか?
殺虫剤やバルサン、農薬などで私達は毎年のように大量の害虫を殺している。
そしたら、あの世は恐ろしい害虫まみれということになる。
そしたら、あの世は恐ろしいミジンコまみれということになる。
・・・・
そんなのありえないだろう。
だから、死後の世界は存在しない。
それとも、あの世に行けるのは、人間だけということなんだろうか?
ネコや犬はいけないの?
でも、化け猫などのおばけの話はあるよね。
と、いうことは、哺乳類はいけるのかな?
でも、鳥類の化物の話も世界中にある。
と、いうことは鳥類も行けるのかな?
両生類は?魚類は?
・・・・
こちらの考え方でも理論が破綻する。
よって、死後の世界は存在しないと考えるのが一番合理的だ。
説得力がある。
だから、私は、死後の世界は存在しないと思っている。