2013年3月22日金曜日

[32bit/64bit] 思考メモ

[割とOSに関係ない話]
*バイナリの違い
64bitバイナリを吐いてくれるコンパイラで無いといけない

*バイナリの種類
windows -> PE形式
UNIX -> a.out ELF形式

[Windowsの話]
*32bit/64bitバイナリの見分け方
http://kuni255.blogspot.jp/2013/03/windows32bit64bit.html
*32bit/64bitプロセスの見分け方
タスクマネージャーで。。。
http://kuni255.blogspot.jp/2013/03/windows32bit64bit.html
*(Windows 7の場合)Program Filesに入るか?Program Files(x86)に入るかはインストーラーの設定依存で別にバイナリの種類を見ているわけではない。よって間違ったインストーラーの設定次第では、64bitバイナリがProgram Files(x86)に入ることだって考えられる

[Windows メモリの話]
*とりあえず32bit Kernelか64bit Kernelかは区別しないといけない
*で結局の話ヒープメモリ制限の違いは?
*PAE(Physical Address Extension)も忘れていはいけない
*32bit Kernelだからといって物理メモリ制限が4Gbyteとは限らない(PAE対応のCPUの場合)
*参考になりそうなサイト http://technet.microsoft.com/ja-jp/windows/mark_04.aspx
http://technet.microsoft.com/ja-jp/windows/ee424286.aspx
*解析プログラムでいきなりヒープ不足で死んだりするのか?
*死ぬ前にスラッシングが起こりメモリ不足に気づきそうなものだが?
*単にmallocのエラーハンドリングをしていないだけでは?



[UNIXの話]
*変数のサイズ(範囲)の違い
http://kuni255.blogspot.jp/2012/08/c.html

[ブートプロセス] 思考メモ

[大まかな流れ]
BIOS -> ブートストラップローダー -> GRUB?-> OS
このGRUBの位置づけは正しいか?
UEFI -> … -> OS

*確定1
リアルモード: 8086の名残、メモリ空間の制限1GByte
プロテクトモード: メモリ空間の制限4GByte


*疑問1
BIOSとUEFIの違いは?
UEFIは、プロテクトモードをすっ飛ばしてる?

*思考1
BIOSがHDD等の先頭領域(512KByte)にあるMBRの先頭領域(446Byte)に保存されている。ブートストラップローダーをメモリにロードして制御権を譲る。
-> HDD等と書いたがUSBメモリ等の不揮発性メモリも一緒か?

そして、ブートストラップローダーは、MBR内のパーティションテーブル(パーティションタイプ(NTFS,ext4)や総セクタ数が定義されている)のブートフラグが立っているパーティションの先頭セクタをメモリにロードして制御権を譲る。
(この辺の参考サイト) http://d.hatena.ne.jp/syuu1228/20130103/1357165915

だが、GRUBの場合はこの限りではない
GNU GRUBのメンテナをされているokujiさんのご講演
http://www.youtube.com/watch?v=nZw8XEAmu5c

*疑問2
このへんがWindowsとlinuxのマルチブート環境構築時のOSのインストール順序を決定づけている? Windowsは、linuxのことなんかお構いなしに自身のブートローダーをGRUBの上に書きこんでしまう?



[NoSQL] MongoDB を触ってみた

FreeBSD(9.0-RELEASE)での記事です。
この記事は、技評の記事を大いに参考にさせていただいています。

[0] インストール
cd /usr/ports
make quicksearch name=mongodb
で検索
cd /usr/ports/databases/mongodb

make configrecursive
make
make install
make clean
でインストールされたのは、下記のバージョン
db version: 2.2.0 pdfile version: 4.5

[1]データ配置用ディレクトリの作成 と サーバープロセスの生成

mkdir -p /var/db/mongodb
と自分はした、適宜
そして、インストール時に「mongodb」ユーザー/グループが作成されているので
chwon -R mongodb:mongodb /var/db/mongodb
としておく。

mongod --dbpath path-to-db
でサーバープロセスを生成する。path-to-dbの部分には、先程作成したディレクトリへのパスを指定する。
waiting for connections on port 27017
と表示されればおk

[2]使ってみる
mongo
がクライアントコマンド

データベースの作成。
use testdb
SQLならそんなデータベースないと叱られそうだがMongoDBの場合指定したDBがない場合は、作成してくれる。

次に「testcoll」コレクション(RDMSで言うところのテーブル Not SQLなのにこのような例えをするのはナンセンスな気もするが。。。)を作成してそのコレクションにドキュメント(RDMSのレコード的な)を挿入する

db.testcoll.insert("key1", "string",  "key2", 132)

JSONのハッシュ形式になっています。

ドキュメントの参照は、
db.testcoll.findOne()["key1"]

2013年3月21日木曜日

[SQL] 最大値を持つレコードの抽出

下記のようなDATETIME型のレコードを格納したテーブル(atndRecords)に対して
+------+---------------+---------------------+---------------------+
| id   | name          | comeTime            | leaveTime           |
+------+---------------+---------------------+---------------------+
| 2971 | 鈴木 三郎    | 2013-01-29 08:55:00 | 2013-01-29 21:17:00 |
| 3746 | 一宮 三郎    | 2013-01-29 08:55:00 | 2013-01-29 19:56:00 |
| 3374 | 井頭 一郎    | 2013-01-29 08:56:00 | 2013-01-29 18:18:00 |
| 3343 | 佐々木 五郎 | 2013-01-29 08:56:00 | 2013-01-29 17:53:00 |
| 2909 | 鈴木 一郎    | 2013-01-29 08:56:00 | 2013-01-29 17:46:00 |
| 3498 | Harry Potter     | 2013-01-29 08:58:00 | 2013-01-29 22:02:00 |
| 3188 | 佐藤 五郎    | 2013-01-29 09:00:00 | 2013-01-29 20:37:00 |
| 3715 | 一宮 二郎    | 2013-01-29 09:59:00 | 2013-01-29 18:14:00 |
                             …
+------+------------------+---------------------+---------------------+

comeTimeが最大(一番遅い)のレコードを抽出するには、サブクエリを使って

select * from atndRecords where comeTime = ( select max(comeTime) from atndRecords);

とすればよい。なお、comeTimeの任意範囲内での最大値を持つレコードを抽出したいい場合は、

select * from atndReocrds where comeTime = ( select max(comeTime) from atndRecords where comeTime >= 2013-01-29 and comeTime < 2013-01-30 );

とサブクエリのwhere句内で範囲を指定すればいい。

2013年3月6日水曜日

Windowsな環境の32bit/64bitとか

まずは、メモ

ある程度知識が溜まったらまとめエントリ書くかも

[32bitバイナリか64bitバイナリかの判断]
PE(Portrable Executable)形式の場合

PEヘッダを見れば判断できる。
PEヘッダは、0x50450000 (PE\0\0) という規定値で始まる。
そして、それに続く2byteで32bit/64bitバイナリかの判断ができる。

0x14c の場合 x86向けバイナリ
0x6486の場合 x86-64向けバイナリ

*ここで注意なのは、ご使用のプロセッサがリトル・エンディアンの場合は、バイナリエディタでは、0x8664が0x6486と表示されます。


PEフォーマットについては、
https://code.google.com/p/corkami/wiki/PE101

がチートシートを公開してくれてます。



[実行中のプロセスが32bitか64bitか]
タスクマネージャーのプロセス名に「*32」がついていれば、それは32bitのプロセスです。




また、Windowsも絡めた話は、
http://blogs.msdn.com/b/nakama/archive/2008/10/30/part-1-64-windows-os.aspx

の記事が精緻にまとめられています。

2013年3月4日月曜日

[php] preg_match

正規表現って使うツールによって微妙に表現が異なるのが嫌

PHPでも案の定ひかかった。
mysqlで言うところのDATE型(ex.2013/03/04)にマッチさせようと
preg_match("/[0-9]\{4\}\/[0-1][0-9]\/[0-3][0-9]/", $target, $mtached);
とやってしまっていた。繰り返しを表す部分\{4\}の中カッコのエスケープは必要ない。
正しくは、
preg_match("/[0-9]{4}\/[0-1][0-9]\/[0-3][0-9]/", $target, $mtached);

こちらでlibpcreの正規表現について説明されている。