常用SQL语句

今天一个朋友问我,一个表有两个字段mac和ip,如何找出所有的mac相同而ip不同的记录?想了半天写出了下面的这个SQL语句。

mysql> select * from ip;
+-----+-----+
| mac | ip  |
+-----+-----+
| abc | 123 |
| def | 456 |
| ghi | 245 |
| abc | 678 |
| def | 864 |
| abc | 123 |
| ghi | 245 |
+-----+-----+
7 rows in set (0.00 sec)

mysql> SELECT  DISTINCT a.mac, a.ip
    -> FROM ip a, ip b
    -> WHERE a.mac = b.mac AND a.ip <> b.ip ORDER BY a.mac;
+-----+-----+
| mac | ip  |
+-----+-----+
| abc | 678 |
| abc | 123 |
| def | 864 |
| def | 456 |
+-----+-----+
4 rows in set (0.00 sec)

(Read More)

你可能不知道的 Java 小知识

本文总结了Java中很容易误解的一些知识点。

(Read More)

论坛转换报告

我们原有的论坛使用的是基于 ASP 的 LeadBBS,后来由于服务器出现了一些小故障,导致 RegExp 对象不能用,于是论坛的许多用到正则表达式的功能全部失效。后来考虑将论坛整个转移到 PHP 系统上。而我维护的另一个论坛使用的是 NewvBB,这个系统是基于国外最流行的 vBulletion 修改而成的,该论坛相当成熟,管理功能也十分强大,于是就准备把论坛移动到 vBulletion 系统上。

(Read More)

PowerPC交叉编译环境的制作(二)

昨天编译完binutils就一点多了,……困啊。今天继续。

首先需要把环境变量重新设置一下(因为昨天关机了):

 $ export TARGET=powerpc-kurobox-linux-gnu
 $ export PREFIX=/home/charlee/cross/tools 

然后我们准备开始编译gcc的第一遍。编译之前首先要准备好两个东西,一个是C语言库的头文件,一个是内核源码的头文件。昨天我们已经解压了glibc和kernel,现在只需要把这些头文件复制到目标目录下面就可以了。

 $ cp -a glibc-2.3.5/include/ $PREFIX/$TARGET
 $ cp -a linux-2.6.11.11/include/linux/ $PREFIX/$TARGET/include
 $ cp -a linux-2.6.11.11/include/asm-ppc/ $PREFIX/$TARGET/include
 $ cd $PREFIX/$TARGET/include
 $ ln -s asm-ppc asm

之后回到工作目录 /home/charlee/cross 下,为gcc建立编译目录:

 $ mkdir gcc-build-bootstrap

编译gcc:

 $ cd gcc-build-bootstrap
 $ ../gcc-4.0.0/configure --target=$TARGET --prefix=$PREFIX \ 
   --without-headers --with-newlib --with-gnu-as --with-gnu-ld \ 
   --with-local-prefix=${PREFIX}/${TARGET} --disable-shared
 $ make all-gcc

结果编译时报告 pthread.h 和 unistd.h 出错。

(Read More)

PowerPC交叉编译环境的制作(一)

第一天

首先确定自己的需求:Host为 i386, Linux; Target为 powerpc, Linux。本来想使用 i386/cygwin 作为host,但是觉得实在难度太大,反正我还有一台Linux主机闲置,就先做成 i386/Linux的host吧。

必不可少的自然是查找相关资料了。找来找去最后找到了这个网站:

根据该网站的介绍,建立交叉编译环境需要四个步骤:

  1. 建立生成目标代码的binutils;
  2. 建立生成目标代码的 gcc 框架;
  3. 建立运行库;
  4. 生成最终的 gcc。

首先将必须的软件包下载。好在 binutils、gcc、glibc 都可以在 http://ftp.gnu.org/gnu/ 下找到,不算很麻烦。最新版本分别为 binutils-2.16、gcc-4.0.0、glibc-2.3.5。另外别忘了同时下载 glibc-linuxthreads。另外,编译 gcc 时需要用到内核头文件,所以顺便将最新的内核下载。最新版本为 2.6.11.11,位于 http://www.kernel.org/ 。

然后在 Host 上建立工作目录,并在其中为最后生成的交叉编译工具建立目录:

$ cd /home/charlee
$ mkdir -p cross/tools

最后将下载的软件全部复制到 cross 目录中并解压缩。

$ cd /home/charlee/cross
$ tar xzvf binutils-2.16.tar.gz
$ tar xzvf glibc-2.3.5.tar.gz
$ tar xzvf glibc-linuxthreads-2.3.5.tar.gz
$ tar xjvf gcc-4.0.0.tar.bz2
$ tar xjvf linux-2.6.11.11.tar.bz2

然后设置环境变量以方便以后的工作:

$ export TARGET=powerpc-kurobox-linux-gnu
$ export PREFIX=/home/charlee/cross/tools

下面开始编译 binutils。binutils的说明文件中建议不要在binutils的源码目录中进行编译,所以我们为它建立编译目录,并进行配置和编译。

$ cd /home/charlee/cross
$ mkdir binutils-build
$ cd binutils-build
$ ../binutils-2.16/configure --target=$TARGET --prefix=$PREFIX
$ make all install

安装结束之后,就可以在 /home/charlee/cross/tools 目录下看到开发工具了。

(Read More)

Oracle中NULL值相关问题

NULL值不等于0,也不等于空,它表示该值不定。

任何运算(加减乘除、字符串连接等)的运算数中包括NULL值时,整个表达式的值即为NULL。使用单行函数对NULL值进行处理,得到的结果也为NULL(NVL等函数除外)。

但是NULL值的布尔运算结果并不一定是NULL,例外的情况为,FALSE AND NULL 结果为FALSE,TRUE OR NULL 结果为TRUE。这是因为在AND运算时只要有一个运算数为FALSE结果即为FALSE,即使另一个运算数为NULL,结果也是一定为FALSE的。反之OR运算中,只要有一个运算数为TRUE,结果即为TRUE。

分组函数均忽略NULL值。

排序时,NULL被看作是最大的值,即正序时NULL显示在最下方,逆序时NULL显示在最上方。

处理NULL值的函数有如下几个:

  • NVL(参数1, 参数2):如果参数1不为NULL,则返回参数1;如果参数1为NULL,则返回参数2
  • NVL2(参数1, 参数2, 参数3):如果参数1不为NULL,则返回参数2;如果参数1为NULL,则返回参数3。该函数的返回值的类型总是与参数2相同,当参数1为NULL时,Oracle会将参数3转换成参数2的数据类型之后再返回。
  • NULLIF(参数1, 参数2):如果参数1等于参数2,则返回NULL;如果参数1不等于参数2,则返回参数1。
  • COALESCE(参数1, 参数2, …, 参数n):返回参数1到参数n中第一个不为NULL的值。

(Read More)

Linux 下使用 PCMCIA 设备

Linux 对 PCMCIA 设备提供了很好的支持。本文简单介绍了Linux下PCMCIA设备的安装方法。

(Read More)

在 Linux 中使用动态磁盘

是否遇到过这样的问题,划分了 10G 的一个分区,挂接到 /home 下,可是随着时间的流逝,10G 的空间开始不够用了,需要把它扩充。假设要扩充到 12G,那么唯一的方法就是建立一个 12G 的新分区,然后将原来的 10G 分区中的数据全部移动到新分区中,再修改挂接配置。这样不仅麻烦而且浪费时间。

Linux 2.4 开始支持 LVM(Logical Volume Manager,逻辑卷管理器),通过 LVM,可以动态地改变“分区”(准确地说应当称之为卷)的大小,而不必担心数据移动的问题。LVM 的原理是,首先在硬盘上创建 PV(Physical Volume: 物理卷)。PV 可以创建在一个分区上,也可以创建在整个硬盘上,它由许多的 PE(Physical Extent)组成,每个 PE 的默认值为 4MB。之后将数个 PV 合在一起组成一个 VG(Volume Group: 卷组)。最后在 VG 中创建 LV(Logical Volume: 逻辑卷),它也由许多的 LE(Logical Extent)组成,LE 的大小与 PE 相同,并与 PE 一一对应。LV 就可以像普通的分区一样挂接在任何地方了。

(Read More)

init配置文件说明

Linux 内核启动之后,启动的第一个进程就是 init 进程。该进程从 /etc/inittab 文件中读取配置,对系统进行一系列的初始化工作。下面我们来分析一下 /etc/inittab 文件的结构。

(Read More)

Linux 的启动过程

  1. 系统启动时,首先由固化在硬件中的 BIOS 对硬件进行初始化,然后读取硬盘的 MBR 上的引导程序。

    • BIOS: Basic Input/Ouput System,基本输入输出系统,固化在系统中的代码,用于完成最底层的硬件操作。
    • MBR: Master Boot Record,主引导记录,位于第一块硬盘的第一个扇区,大小为512字节。其中前 446 字节为引导程序,之后的 64 字节为分区表,最后的两字节为结束标记。
  2. MBR 中的 stage1 执行,并跳转到硬盘上保存的引导程序的剩余部分(即stage2)。

    stage1stage2: MBR 中保存的为 Linux 引导程序( Linux Boot Loader) 的第一部分(即stage1)。由于一般的引导程序都很大,无法放到 MBR 的 446 字节中,因此只将一部分放到 MBR 中,这一部分称为 stage1,用于将引导程序的剩余部分(即stage2)读入并执行。

  3. stage2 执行,并读取 Linux 内核。
  4. 内核执行,对各种硬件进行检测和初始化。
  5. 内核启动 init 进程。

    init进程: 为 Linux 系统中启动的第一个进程,PID 为 1,其它所有的进程都为该进程的子进程。

  6. init 进程按照 /etc/inittab 的指示进行系统初始化工作。一般包括启动各种服务,并启动数个虚拟终端供用户登录。

(Read More)