看书的时候千万别让我发现,否则明天我的电脑就会多一份PDF文件或者快递就会敲我家的门。这本书是Deltamaster测试PDF软件的时候被我看到的,第二天我就下到了这本书的PDF,仔细翻看,果然是好书。虽然是大陆作者所著,但本书不断的用生活中喜闻乐见的实例生动阐述了原本枯燥的操作系统原理,使那些难点和模糊点不再难懂,我只看了一会,就明显感觉对操作系统原理的理解明显加深,有些过去的疑问也在书中得到了解答。这类书籍在普遍死板的大陆作者中确实非常少见。因此推荐给热爱操作系统的同学们。

至于下载地址神马的,God Bless Google!

今天中华民国建国九十九周年和Ubuntu 10.10发布之日,可谓双喜临门。更巧合的是,二者都以自由作为自己的信仰。

文泉驿,是Linux下最著名的自由中文字体,对于他的微米黑字体,我更是爱不释手,所有的实验报告都坚决使用它,即使是要放到Windows下,我也会将文档转换成pdf格式,以极大程度的使用它。如果查看本博客的CSS代码,也可以发现,正文字体文泉驿微米黑排名第一,在其他博客里,我自己还真没见过第二个这么做的。

平日里我装Ubuntu的时候习惯使用纯英文版,一方面是认为Linux用中文没有意思,如果用终端更不方便,另一方面也是想创造点英语气氛,但是Ubuntu有一点很奇怪,如果安装纯英文的Ubuntu,那么中文就显示得不正常,字的大小粗细都很奇怪,尤其是在Google Chrome下,上Ubuntu中文论坛,尤其明显。当然不允许这种事情发生,所以我每次都把Chrome的每一种字体都显式的指定为文泉驿微米黑,有时,甚至把全系统的字体都指定为文泉驿微米黑,似乎不是什么好事,为了一个中文字体,放弃了所有的英文字体。所以我探索新的方法,终于找到了通过修改字体配置文件/etc/fonts/local.conf来把中文字体指定为文泉驿微米黑,而不改变英文字体的方法:

<fontconfig>
   <match target="pattern">
      <test qual="any" name="family">
         <string>serif</string>
      </test>
      <edit name="family" mode="prepend" binding="strong">
         <string>Ubuntu</string>
         <string>WenQuanYi Micro Hei</string>
         <string>AR PL UMing CN</string>
         <string>AR PL ShanHeiSun Uni</string>
         <string>Bitstream Vera Serif</string>
         <string>DejaVu Serif</string>
         <string>AR PL UKai CN</string>
         <string>AR PL ZenKai Uni</string>
      </edit>
   </match> 
   <match target="pattern">
      <test qual="any" name="family">
         <string>sans-serif</string>
      </test>
      <edit name="family" mode="prepend" binding="strong">
         <string>Ubuntu</string>
         <string>WenQuanYi Micro Hei</string>
         <string>Bitstream Vera Sans</string>
         <string>DejaVu Sans</string>
         <string>WenQuanYi Zen Hei</string>
         <string>AR PL UMing CN</string>
         <string>AR PL ShanHeiSun Uni</string>
         <string>AR PL UKai CN</string>
         <string>AR PL ZenKai Uni</string>
      </edit>
   </match> 
   <match target="pattern">
      <test qual="any" name="family">
         <string>monospace</string>
      </test>
      <edit name="family" mode="prepend" binding="strong">
         <string>WenQuanYi Micro Hei Mono</string>
         <string>Bitstream Vera Sans Mono</string>
         <string>DejaVu Sans Mono</string>
         <string>WenQuanYi Zen Hei</string>
         <string>AR PL UMing CN</string>
         <string>AR PL ShanHeiSun Uni</string>
         <string>AR PL UKai CN</string>
         <string>AR PL ZenKai Uni</string>
      </edit>
   </match> 
</fontconfig>

编辑/etc/fonts/local.conf,把上述XML复制进去即可。如果没有该文件,就创建一个。修改后无需重启,即时起效。

最后赞美下Ubuntu 10.10的新字体"ubuntu",很漂亮。刚刚已经修改博客支持这个字体作为默认英文字体了。

参考文献:forum.ubuntu.org.cn/viewtopic.php?f=8&t=236013&start=0

对获取设备描述表的简单总结

2010年10月09日 18:13

昨天晚上一直在纠结于绘图的问题。相同的创建删除DC的代码,放在WM_PAINT里是对的,放进WM_CREATE和WM_DESTROY就全错了,不知道为什么,后来才想起来,不同的事件必须用不同的创建DC的函数,不能混用。

WM_PAINT里要用BeginPaint和EndPaint函数来取得DC,进行重绘。

WM_CREATE里必须用GetDC来取得DC,ReleaseDC既可以在WM_CREATE,也可以在WM_DESTROY里,实现DC在全局有效。

GetWindowDC获取整个窗口的DC,连同客户区和非客户区,WM_NCPAINT(NC是非客户区,不是脑残)事件负责对非客户区的重绘。ReleaseDC负责删除它。

CreateDC获取整个屏幕的DC,似乎不仅限于屏幕使用,具体怎么用,我也不知道。由DeleteDC负责删除。

至于CreateCompatibleDC想必就不用说了。这函数名字起的不好,叫缓存DC还差不多。

就是这样~~最后热烈庆贺中国再获诺贝尔和平奖。

关于C execlp函数的理解

2010年9月29日 19:05

execlp(從PATH 環境變量中查找文件並執行)

相關函數
fork,execl,execle,execv,execve,execvp
表頭文件 #include<unistd.h>
定義函數 int execlp(const char * file,const char * arg,……);
函數說明
execlp()會從PATH 環境變量所指的目錄中查找符合參數file的文件名,找到後便執行該文件,然後將第二個以後的參數當做該文件的argv[0]、argv[1]……,最後一個參數必須用空指針(NULL)作結束。
返回值
如果執行成功則函數不會返回,執行失敗則直接返回-1,失敗原因存於errno 中。
錯誤代碼
參考execve()。
範例
	/* 執行ls -al /etc/passwd execlp()會依PATH 變量中的/bin找到/bin/ls */
#include<unistd.h>
main()
{
    execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
}
//執行
//-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd

其实上面的描述很奇怪,如果能从PATH中找到第一个参数指定的文件,那何须第二个参数呢,没意义啊?

然后Google了下,看到了www.lslnet.com/linux/f/docs1/i34/big5260214.htm中别人同样的质疑。

这张帖子的楼主索性猜测:execlp函數在實際執行的時候根本沒有用到第二個參數。

说真的,这个猜测过于草率了。

楼下有一张回帖给出了一个反例:execlp("ls","flw","-?",(char *)0)。

应该是execlp("ls","flw","--help",(char *)0)吧,ls是Linux命令,-?是Windows的写法,不能同时运用,疑为他的笔误。这句语句在我电脑上的效果:

Usage: flw [OPTION]... [FILE]...

List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort.
 
自已在终端上永远试不出这个结果,因为明明调用的是ls命令,不可能显示出Usage: flw来。
再仔细看看上面关于这个函数的描述“然後將第二個以後的參數當做該文件的argv[0]、argv[1]……”
我猛然想到了以前说过main函数是可以传入参数的,我于是尝试了这样的代码:
	int main(int num_args,const char* args[])
{
	for(int i=0;i<num_args;++i)
	{
		std::cout << args[i] << std::endl;
	}
        return 0;
}

在终端而不是IDE里运行这个程序,运行的时候给他带点参数,结果自己打的命令出现的在args[0]的位置,后面的参数出现在了args[1],args[2],args[3]....的位置,可见C程序总会把你运行这个程序用的命令传入args[0]。这样这个问题就解开了。execlp第一个参数是让程序从PATH中找到指定程序运行,第二个参数将传入这个程序的args[0]。

execlp("ls","flw","--help",(char *)0)出现Usage: flw,是因为ls命令在显示帮助的时候会动用args[0],这么设计很正常,因为如果用户打错了命令,总希望用最接近他命令的方式指导他怎么做才对,直接使用他的命令是最方便的。平时args[0]几乎总是等于ls,这是因为ls在PATH中,没必要指示他的位置,但如果使用/bin/ls这样的命令,就可以看出来了。

twitter logo GDI绘制

2010年9月27日 07:09

这次的作业,用GDI绘制任意卡通图,我不会画什么卡通图,于是就画了个twitter的logo。

按1(MM_TEXT),7(MM_ISOTROPIC),8(MM_ANISOTROPIC)会有不同的GDI映射。缩放窗口可以看出他们的区别。

继续阅读

相信C++中Private和Protected继承是最冷门的语法之一吧,以至于以后大多数以C++语法作为模板的语言都没有继承这个语法。我C++学的不算差,学完后几乎每学期都在使用,但是也把这个语法点忘的差不多了。不过今天在和Deltamaster讨论C++如何选择性继承的时候(只继承一部分接口,另一部分接口不继承,如果用户去使用这些不被继承的接口,必须在编译期间报错),他提出了用Protected或Private继承的思想。实现如下:

#include<iostream>
class Parent
{
public:
	void get()
	{
		std::cout << "get" << std::endl;
	}
	void set()
	{
		std::cout << "set" << std::endl;
	}
};
class Child:protected/*private*/ Parent
{
public:
	void get()
	{
		Parent::get();
	}
};
int main()
{
	Child c;
	c.get();
	//c.set();
	system("pause");
	return 0;
}

允许子类继承父类的get方法,而不继承set方法,就是先让子类Protected(或Private)继承父类,使父类所有接口在子类中一律为Protected(或Private),然后重写一个Public的get方法,在其中调用父类的get方法即可,这样就可以做到正常调用子类继承自父类的get方法,而如果调用子类继承自父类的set方法就会编译出错。

以上代码是在Microsoft Visual Studio 2010编写并编译的,本来想在Linux下用Eclipse写,但总感觉CDT有BUG,编译通不过,所以还是在Visual Studio下写。下次装Eclipse再也不装CDT了。

一直不知道Java中Finally的作用,因为总感觉没有什么用,事实上,当初学Javascript时也有同样的疑问,后来Google下,才明白过来。

	public void writeFile(String filePath, String fileName, String args) throws IOException
{
    FileWriter fw = new FileWriter(filePath + fileName);
    try 
    {
        fw.write(args);
    }
    catch (IOException e)
    {
    //1
        fw.close();
        throw e;
    }
    //2
    fw.close();
}
 
这段代码创建了一个FileWriter object,并调用 write 方法。在退出该方法之前,您必须关闭FileWriter object,以避免资源漏洞。为了完成这一任务,我们在 //2 处调用 close,它是该方法的最后一条语句。但是,如果 try 块中发生一个异常会怎么样呢?在这种情况下,//2 处的 close 调用永远不会发生。因此,您必须捕获这个异常,并在重新发出这个异常之前在 //1 处插入对 close 的另一个调用。这样就可以确保在退出该方法之前关闭FileWriter object。这样编写代码既麻烦又易于出错,但在没有 finally 的情况下这是必不可少的。有了 finally,前面的代码就可以重写为以下的形式:finally 关键字是对 Java 异常处理模型的最佳补充。 finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。如果没有 finally,您的代码就会很费解。例如,下面的代码说明,在不使用 finally 的情况下您如何编写代码来释放非内存资源:
 
	public void writeFile(String filePath, String fileName, String args) throws IOException
{
    FileWriter fw = new FileWriter(filePath + fileName);
    try 
    {
        fw.write(args);
    }
    catch (IOException e)
    {
        throw e;
    }
    finally 
    {
        fw.close();
    }
}
 
finally 块确保 close 方法总被执行,而不管 try 块内是否发出异常(或是try块中有突如其来的return)。因此,可以确保在退出该方法之前总会调用 close 方法。这样您就可以确信FileWriter object被关闭并且您没有泄漏资源。
 
参考文献:
tech.ccidnet.com/art/3737/20060510/549039_1.html
hi.baidu.com/laoyouji2008/blog/item/d96467092d28f02f6b60fbb6.html
 
对于一些无可奈何的二元操作(神马是二元操作?二元操作是指当调用一个函数后必须成对调用另一个函数,这两个函数总是成对使用,否则可能会导致严重错误。比如文件的打开和关闭,加锁和释放锁。二元操作本身不是难点,但是人们非常容易忘记调用第二个函数,从而造成隐患,这在一个代码块中有多个如return,break,continue之类跳转语句时极易发生,以前有本书希望我们永远在代码块中只设定一个出口,但是这么做难度很大),由于Java的析构函数总不是很给力(无法确定何时调用,是否会调用,不能用它来包装第二个操作,这和C++完全不一样),我们完全可以使用Finally来完成第二个操作,这样就不会遗忘了。我们只要让第一个操作的那个代码块被try包围,第二个操作写在之后的finally中,catch可以不需要,这样无论接下来有多少个可能导致跳出代码块的语句,第二次操作总会被执行,毋须任何担忧。

安装Proftpd的几点总结

2010年9月18日 07:23

过去Proftpd总尽可能采用自动化安装+图形化使用的办法,偷懒,但是今天安装Proftpd我则采用了官方下载源码+自行编译+文本文件配置FTP,难度毫无疑问比之前大些,但也难不到哪里去。

安装方法详见《鸟哥的Linux私房菜》 linux.vbird.org/linux_server/0410proftpd.php 这里只总结一些鸟哥没有说的部分。

(话说这本书写得真好,通俗易懂,语言幽默,不愧是自由中国啊,令人神往。)

总结一:安装Proftpd出现如下错误:

tcpwrap.c:15:20: error: tcpd.h: No such file or directory

使用apt-get install libwrap0-dev即可。

总结二:中文问题,这个问题真的令人头疼,目前我也没有找到完全解决的办法,只能不断弱化这种错误

在鸟哥那句 ./configure --prefix=/usr/local/proftpd --enable-shadow --enable-autoshadow --with-modules=mod_ratio:mod_readme:mod_wrap 中再增加一个参数 --enable-nls

编译安装后,在proftpd.conf里增加一项:UseEncoding UTF-8 GBK,即可。

这么做的话,当从Windows的客户端或Linux的FTP服务器放入中文文件时他们互相访问都不会有问题,但这时使用Linux的客户端去访问Linux的FTP服务器,则文件名会有乱码(内容不会,似乎是Linux的FTP客户端编码和人家都不一样),不知道如何解决。

参考文献:

www.xpv.cn/home/vsftpdbianyicuowujiejuebanfa.html
blog.wu-boy.com/2010/07/07/2276/

继续阅读

由于电脑重装的缘故,我虚拟机里的Oracle数据库也重新安装了,因为OCP已经考完,我配置的数据库显然不能再局限于OCP考试之用,再说我本来也喜欢开发,而不是做DBA,我计划着让他和PHP连接起来,模仿生产环境,所以在编码上我使用了UTF-8字符集,而不是传统的美式字符。安装自然是一切顺利,不过在打开EM时却发生了java.lang.Exception: Exception in sending Request::null的错误,这个错误以前从未发生过,重启也无效。我估摸着大概是字符集的问题,于是Google下,找到了解决方法:

gedit $ORACLE_HOME/sysman/config/emd.properties

在最后添加agentTZRegion=Asia/Shanghai 重启EMCTL就可以了。

我在上海,所以使用上海的时区。

可以使用 gedit $ORACLE_HOME/sysman/admin/supportedtzs.lst 来找到支持的时区。

参考文献:

hi.baidu.com/zxq211103/blog/item/f00a7a63ad47fc620c33fa0d.html
forums.oracle.com/forums/thread.jspa?threadID=320574&tstart=0&messageID=1374397

1.由于我的一位同学(网名:Deltamaster,域名:softrank.net,我是他的粉丝)对这个脚本的“自动跳转模式”感觉非常困惑,而我确实也难以向他解释,所以放弃了这个功能(因为我是他的极品粉丝)。当初这个功能完全是因为一时脑残,否决了之前的一个功能,又懒得修改已有的代码,所以随便拿另一个功能去替换而已。这个功能本来也确实不需要。

2.默认不再显示那些控件,因为默认设定是我认为最人性化的设定。我现在也认为事先作出最完美的设定,不再需要用户自己动手,同时也可以除去一些无用的控件来使界面更简洁是正确的。不过我仍然保留用户可以自行修改的权利。所以display这个参数依旧存在,修改为true就可以显示所有控件。

Userscript地址: userscripts.org/scripts/show/84200

谷奥地址:guao.hk/posts/super-google-dictionary-greasemonkey-user-script.html

Chrome迷地址:chromi.org/archives/6785