2014年7月15日星期二

阮一峰的网络日志

阮一峰的网络日志


中文字体网页开发指南

Posted: 14 Jul 2014 05:43 PM PDT

字体的选择,是网页开发的关键因素之一。

合适的字体,对网页的美观度(或可读性)有着举足轻重的影响。

但是,相比英文字体,中文字体的网页开发有着极大的局限性。因为,一套中文字体最少也要有几千个字符,体积为几个MB;单单为了浏览网页,开发者不可能让用户去下载字体,只能依靠操作系统的预装字体。(*注:确实有网站提供中文字体的web服务,从技术角度,我不推荐这样做。)

不同的操作系统、不同的版本预装不同的字体(因为版权),几乎没有交集。因此,大多数开发者索性忽略中文字体,让操作系统自行渲染,或者用图片呈现字体效果。

下面是目前中文字体的最佳实践,主要参考了Kendra Schaefer的文章。

一、操作系统的预装字体

操作系统决定了开发者可以使用的字体。所以,第一步,我们必须了解操作系统到底提供哪些字体。

Windows操作系统

  • 黑体:SimHei
  • 宋体:SimSun
  • 新宋体:NSimSun
  • 仿宋:FangSong
  • 楷体:KaiTi
  • 仿宋GB2312:FangSongGB2312
  • 楷体GB2312:KaiTiGB2312
  • 微软雅黑:Microsoft YaHei (Windows 7开始提供)

OS X操作系统

  • 冬青黑体: Hiragino Sans GB (SNOW LEOPARD开始提供)
  • 华文细黑:STHeiti Light (又名STXihei)
  • 华文黑体:STHeiti
  • 华文楷体:STKaiti
  • 华文宋体:STSong
  • 华文仿宋:STFangsong

如果用户装了MicroSoft Office,还会多出一些字体。

  • 隶书:LiSu
  • 幼圆:YouYuan
  • 华文细黑:STXihei
  • 华文楷体:STKaiti
  • 华文宋体:STSong
  • 华文中宋:STZhongsong
  • 华文仿宋:STFangsong
  • 方正舒体:FZShuTi
  • 方正姚体:FZYaoti
  • 华文彩云:STCaiyun
  • 华文琥珀:STHupo
  • 华文隶书:STLiti
  • 华文行楷:STXingkai
  • 华文新魏:STXinwei

二、font-family命令

CSS的font-family命令,指定了网页元素所使用的字体。下面是一个例子。

 font-family: Georgia, "Times New Roman",               "Microsoft YaHei", "微软雅黑",               STXihei, "华文细黑",               serif;  

它的规则有三条。

(1)优先使用排在前面的字体。

(2)如果找不到该种字体,或者该种字体不包括所要渲染的文字,则使用下一种字体。

(3)如果所列出的字体,都无法满足需要,则让操作系统自行决定使用哪种字体。

根据这些规则,font-family应该优先指定英文字体,然后再指定中文字体。否则,中文字体所包含的英文字母,会取代英文字体,这往往很丑陋。

上面图片中,红框内的英文字母,左边采用英文字体渲染,右边采用中文字体渲染,哪一种效果比较好,一目了然。

为了保证兼容性,中文字体的中文名称和英文名称,应该都写入font-family。比如,"微软雅黑"的英文名称是Microsoft YaHei。

此外,中文字体的中文名称,以及由多个单词组成的英文名称,应该放在双引号内。

三、 Windows平台和Mac平台

由于Windows和Mac的中文字体没有交叉,所以应该同时为两个平台指定字体。

常见的做法是,Windows平台指定"微软雅黑"(Microsoft YaHei),Mac平台指定"华文细黑"(STXihei)。

四、衬线体和无衬线体

所谓"衬线体"(Serif),指的是笔画的末端带有衬线的字体。

就像英文字体一样,中文字体也可以分成"衬线体"和"无衬线体"(San-serif)。比如,对于繁体字来说,微软正黑(Microsoft JhengHei)是无衬线体,新细明体(PMingLiU)是衬线体。

对于简体字来说,微软雅黑(Microsoft yahei)是无衬线体,宋体(SimSun)是衬线体。

一般来说,衬线体装饰性强,往往用于标题;无衬线体清晰度好,往往用于正文。

五、几种常见中文字体

(1)宋体(SimSun)

宋体是最常见的中文字体,如果没有指定字体,操作系统往往选择它来渲染。很多人认为,这种字体并不美观。

(2)微软雅黑(Microsoft YaHei)

微软雅黑的美观度和清晰度都较好,可以作为网页的首选字体。它在Mac平台的对应字体是华文细黑(STXihei)。

但是,Windows XP没有预装这种字体,这时可以选择黑体(Simhei)替代。不过,黑体比较粗,不应用于字号较小的文字。

(3)仿宋(FangSong)

这种字体是衬线体,比宋体的装饰性更强。如果字号太小,会影响清晰度,所以只有在字号大于14px的情况下,才可以考虑这种字体。

它在Mac平台的对应字体是"华文仿宋"(STFangsong)。

(4)楷体(KaiTi)

楷体也是衬线体,装饰性与仿宋体接近,但是宽度更大,笔画更清楚一些。这种字体也不应该在小于14px的情况下使用。

它在Mac平台的对应字体是"华文楷体"(STKaiti)。

(完)

文档信息

2014年7月4日星期五

阮一峰的网络日志

阮一峰的网络日志


数据库的最简单实现

Posted: 04 Jul 2014 12:04 AM PDT

所有应用软件之中,数据库可能是最复杂的。

MySQL的手册有3000多页,PostgreSQL的手册有2000多页,Oracle的手册更是比它们相加还要厚。

但是,自己写一个最简单的数据库,做起来并不难。Reddit上面有一个帖子,只用了几百个字,就把原理讲清楚了。下面是我根据这个帖子整理的内容。

一、数据以文本形式保存

第一步,就是将所要保存的数据,写入文本文件。这个文本文件就是你的数据库。

为了方便读取,数据必须分成记录,每一条记录的长度规定为等长。比如,假定每条记录的长度是800字节,那么第5条记录的开始位置就在3200字节。

大多数时候,我们不知道某一条记录在第几个位置,只知道主键(primary key)的值。这时为了读取数据,可以一条条比对记录。但是这样做效率太低,实际应用中,数据库往往采用B树(B-tree)格式储存数据。

二、什么是B树?

要理解B树,必须从二叉查找树(Binary search tree)讲起。

二叉查找树

二叉查找树是一种查找效率非常高的数据结构,它有两个特点。

(1)每个节点最多只有两个子树。

(2)左子树都为小于父节点的值,右子树都为大于父节点的值。

(3)在n个节点中找到目标值,一般只需要log(n)次比较。

二叉查找树的结构不适合数据库,因为它的查找效率与层数相关。越处在下层的数据,就需要越多次比较。极端情况下,n个数据需要n次比较才能找到目标值。对于数据库来说,每进入一层,就要从硬盘读取一次数据,这非常致命,因为硬盘的读取时间远远大于数据处理时间,数据库读取硬盘的次数越少越好。

B树是对二叉查找树的改进。它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数。

B-tree

B树的特点也有三个。

(1)一个节点可以容纳多个值。比如上图中,最多的一个节点容纳了4个值。

(2)除非数据已经填满,否则不会增加新的层。也就是说,B树追求"层"越少越好。

(3)子节点中的值,与父节点中的值,有严格的大小对应关系。一般来说,如果父节点有a个值,那么就有a+1个子节点。比如上图中,父节点有两个值(7和16),就对应三个子节点,第一个子节点都是小于7的值,最后一个子节点都是大于16的值,中间的子节点就是7和16之间的值。

这种数据结构,非常有利于减少读取硬盘的次数。假定一个节点可以容纳100个值,那么3层的B树可以容纳100万个数据,如果换成二叉查找树,则需要20层!假定操作系统一次读取一个节点,并且根节点保留在内存中,那么B树在100万个数据中查找目标值,只需要读取两次硬盘。

三、索引

数据库以B树格式储存,只解决了按照"主键"查找数据的问题。如果想查找其他字段,就需要建立索引(index)。

所谓索引,就是以某个字段为关键字的B树文件。假定有一张"雇员表",包含了员工号(主键)和姓名两个字段。可以对姓名建立索引文件,该文件以B树格式对姓名进行储存,每个姓名后面是其在数据库中的位置(即第几条记录)。查找姓名的时候,先从索引中找到对应第几条记录,然后再从表格中读取。

这种索引查找方法,叫做"索引顺序存取方法"(Indexed Sequential Access Method),缩写为ISAM。它已经有多种实现(比如C-ISAM库和D-ISAM库),只要使用这些代码库,就能自己写一个最简单的数据库。

四、高级功能

部署了最基本的数据存取(包括索引)以后,还可以实现一些高级功能。

(1)SQL语言是数据库通用操作语言,所以需要一个SQL解析器,将SQL命令解析为对应的ISAM操作。

(2)数据库连接(join)是指数据库的两张表通过"外键",建立连接关系。你需要对这种操作进行优化。

(3)数据库事务(transaction)是指批量进行一系列数据库操作,只要有一步不成功,整个操作都不成功。所以需要有一个"操作日志",以便失败时对操作进行回滚。

(4)备份机制:保存数据库的副本。

(5)远程操作:使得用户可以在不同的机器上,通过TCP/IP协议操作数据库。

(完)

文档信息