Submitted by gouki on 2009, May 2, 7:36 AM
这是一篇来自博客园的文章,感觉里面的一些知识点不错。最后那张图是我一直想要找没有找到的。好像记得每年都会有这种用户行为征测的报告出来,但,因为不知道术语是什么,也就没有找到过。做商业网站的时候,了解这种行为非常重要,只有这样才能知道把重点放在什么位置。
原文:http://www.cnblogs.com/cocowool/archive/2009/05/01/1447466.html
作者:小狼的世界
易用性是什么?
易用性就是是你的网站对用户来说使用更简单,能够让用户在他需要的地方很快找到需要的信息。类比于Google所提倡的”让用户呆在Google的时间不短缩短“,对于网站来说,我们不是减少用户在网站的停留时间,而是缩短用户寻找关键信息和向导的时间。
很多人认为要实现网站的易用性需要耗费大量的人力、财力和物力,确实有很多的大网站他们投入了很多的钱和设备去做网站的易用性的研究和测试,但是对于我们日常的小网站来说,我们仍有方法在没有专家和专业设备的基础上改进网站的易用性。
一、包含宣传词(Tagline)。
宣传词是一个用来表明公司理念、目标或者网站愿景的地方。这一部分应该是网站最引人瞩目的部分,应该用简短的语言概括站点。统计结果表明,一个页面只有8秒钟的时间来吸引一个用户继续他的浏览,所以如果不能用醒目的焦点吸引用户,那这个页面就是失败的。
国外的站点很多使用Tagline或者醒目的Flash,国内的站点也可以 这么用,有的时候内容多的时候,还可以是Banner+焦点图,这个要区分不同的网站类型来对待。例如对于产品型的网站,完全可以只使用一个焦点图或者醒 目的有特色的Flash来吸引注意,如果是资讯类的或者专题类的页面,则可能既要有Banner,来突出这个页面的主题,也要有焦点图,来显示最近的一些 动态。这个需要在制作的过程中不断地体会积累。



二、提供站内搜索。
站内搜索对于用户来说也是非常重要的,特别是当站点的内容量开始逐渐增多以至于用户不能很轻易的找到他想要的东西时,用户往往会想到搜索。 你能想象到,要在博客园里通过连接一个一个查找你之前看到过的某一篇文章的痛苦吧。
搜索框的长度和位置也需要加一点注意,不能太小,位置最好放在右上区域,因为根据用户的浏览习惯呈现出”F“的趋势(F Pattern),提交按钮的文字最好能够明确的告诉用户,接下来将要发生的动作是搜索。

三、不能滥用图片。
从易用性的角度来看,Less Is Always More。
四、使用站点地图。
站点地图是一项能够改进站内导航和搜索引擎优化(SEO)的特性。典型的站点地图提供了站点的结构和各个页面的导航。站点地图可以是任何形式的,可以是一个网页、一些页面的列表,只要他们是按照层级关系组织起来的就行。
最近,Google、Yahoo、MSN开始提供Sitemap Protocol的服务,同站点地图非常相近,但是数据是以XML的形式组织的。
五、不要破坏工作流。
工作流是指用户在网站上所进行的操作,比如填写表单、注册用户、浏览目录、档案等,要允许用户撤销操作,如果没有提供后退或者返回的选项,用户就被逼着做他们不想做的动作,或者他们会干脆关掉浏览器来图个清净。
有些站点上的操作顺序并不是那么的明显,这个时候就需要有提示来指导用户。比如Yahoo Music当第一次进入的时候,会有一个向导来指导你一步一步的熟悉页面上各个功能区。玩游戏的时候也会有游戏教学这个环节,如果网站上也提供了,会带来很好的用户体验。
还有一个误区是改变超链接的样式。传统的门户往往让超链接停留在他原始的样子,这样能够给用户明确的指示,这是一个超链接,通过点击,我可以进入一 个新的页面。当然,我并不赞成超链接的样式一定不能改变,但是如果发生了改变,我们一定需要通过图示或者文字来表明,用户可以通过点击这个链接到达另外一 个页面。
六、让网站更容易被”扫描“。
内容的可读性能够提高用户的忠诚度,让用户停留在站点上获得他们需要的内容。但是研究表明,很多用户并不是在读页面,而是在”扫描“,通过扫描标题、着重文字、强调的列表来获得信息。
Jacbo Nilsen通过视觉追踪发现用户的浏览很像一个F型,他们从左到用从上到下的”扫描“页面。

他的实验同时也得出了一下结论:
用户不是一个字一个字的去阅读,而是从段落、着重文字中提取信息。
文章的前两段非常的重要,这两段必须包括这篇文章的大部分内容。
副标题和列表能够重新引起用户的注意,注意用这些元素来强调重要的内容。
从传统的纸质媒体上得来的经验也告诉我们,将内容组织成一个倒金字塔型。关键问题是,我们如何才能知道什么信息对用户来说是重要的,那些信息对用户来说又是不重要的,作者推荐了一个工具:News Values。
七、不要设计容易误导的界面元素。
千万不要设计那种看上去像是一个按钮实际上不是的内容,我们也经常被那些带下划线的文字误导,当我们点击时,发现他们根本不是链接!
Yahoo是一个很好的正面的例子。
八、给出用户有意义的提示。
这一点大家应该都有共识了,不要将出错信息直接输出到页面上,要给出用户经过处理的、用户能够理解的信息。
九、不要过度使用Javascript。
过度的使用Javascript和Ajax技术,我们需要小心的避免出现浏览器兼容性问题,我们要很好的衡量这个代价。
十、避免验证符。
验证符的使用在必须的地方添加,如果不是那么必要,还是要符合人类懒惰的本性,去掉那些验证符吧。
总结:提升网站的易用性并不一定需要墨守成规,但是在没有足够的功力之前,这些规则能够为我们提供一个很好的方向指向。对于这些规则的争论也很多, 比如避免验证符的使用,在很多情况下,我们必须使用验证符来避免垃圾信息的产生,就像坐飞机时的安检,虽然是一件让人不舒服的事情,可是他有他的目的。
网站的易用性也不是网站的全部,我们必须在易用性、页面设计、站点的可维护性和安全性之间权衡,对不同类型的项目采取不同的处理策略。
参考资料:
[1]、http://www.webdesignerdepot.com/2008/12/10-usability-tips-for-web-designers/
[2]、http://www.useit.com/
[3]、News Values。http://mtsu32.mtsu.edu:11178/171/newsvals.htm#top
Tags: 网站设计, 易用性
PHP | 评论:0
| 阅读:16282
Submitted by gouki on 2009, April 30, 3:41 PM
来自向东:http://www.xiangdong.org/blog/post/1743/
文章太长,不作过多介绍,反正,文章的头部就说明了大概的意思。。。
原文如下:
写了一个简单的队列任务处理。多进程任务,异步任务可能会用到这个(主要是命令行应用)
比如,任务的某个一个环节速度十分不稳定,可能执行几秒,也可能执行几分钟,
我就可以把那个环节包括前面的部分扔进队列,多跑几个进程,同时往队列里面写。
然后后面比较快的环节只跑一个处理任务就OK了。让整体速度达到更好的效果。
write.php: 将任务写入队列
PHP代码
- <?php
-
-
-
-
- function mt($identifier='default')
- {
- return sprintf("%.6f.%s",strtok(microtime(),' ')+strtok(''),$identifier);
- }
-
- while(1)
- {
- if(count(glob('./queue/*.identifier'))>=10)
- {
- sleep(1);
- continue;
- }
- $url = 'www.'.time().'.com';
- echo "$url\r\n";
- $fp = fopen('./queue/'.mt('identifier'),'w');
- fwrite($fp,$url);
- fclose($fp);
- sleep(1);
- }
- ?>
read.php:
PHP代码
- <?php
-
-
-
-
- while(1)
- {
- if($queue = glob('./queue/*.identifier'))
- {
- $q = array_shift($queue);
- $url = file_get_contents($q);
- echo $url."\r\n";
- unlink($q);
- }
- sleep(1);
- }
- ?>
相关的资料:双向队列
baidu和google上没有查到PHP双向队列的资料,搜索到java的双向队列定义如下:双向队列(双端队列)就像是一个队列,但是你可以在任何一端添加或移除元素。
而双端队列是一种数据结构,定义如下:
A deque is a data structure consisting of a list of items, on which the following operations are possible.
* push(D,X) -- insert item X on the rear end of deque D.
* pop(D) -- remove the front item from the deque D and return it.
* inject(D,X) -- insert item X on the front end of deque D.
* eject(D) -- remove the rear item from the deque D and return it.
Write routines to support the deque that take O(1) time per operation.
翻译:双端队列(deque)是由一些项的表组成的数据结构,对该数据结构可以进行下列操作:
push(D,X) 将项X 插入到双端队列D的前端
pop(D) 从双端队列D中删除前端项并将其返回
inject(D,X) 将项X插入到双端队列D的尾端
eject(D) 从双端队列D中删除尾端项并将其返回
编写支持双端队伍的例程,每种操作均花费O(1)时间
百度百科:(deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。
转贴一个使用Php数组函数实现该功能的代码:
PHP代码
- <?php
-
- class DoubleEndedQueue1 {
- var $queue = array();
- function add($var){
- return array_push($this->queue, $var);
- }
- function frontRemove(){
- return array_shift($this->queue);
- }
- function rearRemove(){
- return array_pop($this->queue);
- }
- }
-
-
- class DoubleEndedQueue2 {
- var $queue = array();
- function remove(){
- return array_pop($this->queue);
- }
- function frontAdd($var){
- return array_unshift($this->queue, $var);
- }
- function rearAdd($var){
- return array_push($this->queue, $var);
- }
- }
-
-
- $q = new DoubleEndedQueue1;
- $q->add('aaa');
- $q->add('bbb');
- $q->add('ccc');
- $q->add('ddd');
-
- echo $q->frontRemove();
- echo "<br>";
- echo $q->rearRemove();
- echo "<br>";
- print_r($q->queue);
- ?>
array_push -- 将一个或多个单元压入数组的末尾(入栈)
array_unshift -- 在数组开头插入一个或多个单元
array_pop -- 将数组最后一个单元弹出(出栈)
array_shift -- 将数组开头的单元移出数组
// 来自 PHP5 in Practice (U.S.)Elliott III & Jonathan D.Eisenhamer
PHP代码
- <?php
-
-
- function &queue_initialize() {
-
- $new = array();
- return $new;
- }
-
- function queue_destroy(&$queue) {
-
- unset($queue);
- }
-
- function queue_enqueue(&$queue, $value) {
-
-
- $queue[] = $value;
- }
-
- function queue_dequeue(&$queue) {
-
- return array_shift($queue);
- }
-
- function queue_peek(&$queue) {
-
-
- return $queue[0];
- }
-
- function queue_size(&$queue) {
-
- return count($queue);
- }
-
- function queue_rotate(&$queue) {
-
- $queue[] = array_shift($queue);
- }
-
-
- $myqueue =& queue_initialize();
- queue_enqueue($myqueue, 'Opal');
- queue_enqueue($myqueue, 'Dolphin');
- queue_enqueue($myqueue, 'Pelican');
-
-
- echo '<p>Queue size is: ', queue_size($myqueue), '</p>';
-
- echo '<p>Front of the queue is: ', queue_peek($myqueue), '</p>';
-
- queue_rotate($myqueue);
-
- echo '<p>Removed the element at the front of the queue: ',
- queue_dequeue($myqueue), '</p>';
-
- queue_destroy($myqueue);
- ?>
Tags: 任务队列
PHP | 评论:3
| 阅读:49395
Submitted by gouki on 2009, April 29, 9:50 AM
Zendstudio.net,看这个网站的名称就知道,它是专注于zs工具的。
事实上也确实是这样的。站长还提供了一些KEY的生成工具,阿弥陀佛,罪过罪过。。
站长不但对ZS有研究,同时还本着开源的心态,把自己的一些心得整理出来,是flash的哦。大家可以在线观看。。
站长把一些5.5和6.1的使用教程都列出来了。
如果您是使用6.1的话,那就比较方便了。。。直接打开:http://www.zendstudio.net/zend-studio-tutorial/,就可以看到教程。
- zend studio 6.1中文视频教程-快速入门
- Zend Studio For Eclipse 6.1 视频教程-调试php程序
- 让zend studio for eclipse支持xdebug(视频教程)
- 在zend studio for eclipse中使用xdebug调试php程序
- 在zend studio for eclipse中寻找消失了的zend studio 5.5特色功能(筹备中…)
- 使用profile来优化你的php程序性能,提高程序效率(筹备中…)
新站上只有6.1的教程,如果你还在使用ZS 5.5,不用担心,这里也有:
- 基础部分:
- ZDE的初级安装教程(图)
- Zend Studio 5.5.1 界面详细介绍及菜单、工具栏功能详解(图)
- Zend Studio 首选项(preferences)功能、设定详解(图)
- Zend Studio的特色功能——模板(templates)
- zend studio的特色功能——代码片段(code snippets)
- Zend Studio快捷键一览表
- zend studio 5.5无法打开主界面故障解决方法一例
- 修改zend studio 的默认字体 让编辑器看起来更舒服
- 用Zend Studio管理数据库—zde的SQL管理器功能介绍
- 提高部分:
- 服务器调试——Zend Debugger 的安装教程
- Zend Studio的远程调试(服务器调试)技术 Zend Debugger(一)
- Zend studio的项目管理和服务器调试(视频教程)
-EOF-
写了这么多,也贴了N多链接,就再贴一下zendstudio.net站长的资料吧。。。
大家随便YY去吧
- 昵称:徐徐
- 英文名:gently
- MSN:

- 身高:跟姚明没得比
- 三围:您所在的用户组无权查看该信息
- 介绍:目前处于IT食物链底层,若在万恶的旧社会,那就是被剥削被压迫的那个阶层。
- 人生关键词:积极、自信、踏实。
Tags: zendstudio, php, 教程
PHP | 评论:0
| 阅读:39600
Submitted by gouki on 2009, April 28, 11:05 PM
风雪之隅的网站上大多是对PHP的底层进行关注的文章,如果对PHP的核心内容有兴趣不妨多翻阅一下他的网站。
本文的标题,其实是一个老问题了。
大家都知道,PHP对于没有引号的字符串,会当成常量来处理,如果该常量不存在,则直接输出该字符串。也就是多做了几步处理。
事实上,上面的这个知识点,很早就知道,但,不是我自己研究出来的。虽然自己写过代码进行测试过。
雪候鸟则直接从OPCODE上进行查看,给你一个直观印象。好,我们来看看原文吧
地址:http://www.laruence.com/2009/04/24/695.html
内容:
我看到过很多人操作数组的时候, 对于数组中的非数字键名不使用引号,
PHP代码
- $array[key] = $value;
我可以理解有些人可能会觉得这样的代码很”整洁”, 并且也能正常执行.
更甚至,如果他很”幸运的”php配置的好:
PHP代码
- error_reporting = ~E_NOTICE
他也许永远都沉浸在自己的”整洁”风格中, 看不到任何的NOTICE提示, 也不会意识到, 他这么做, 能损失多少的性能~
来, 我们一起来看看:
PHP代码
- good.php:
- <?php
- $array = array();
- $i = 0;
- while(++$i < 1000){
- $array['good'] = 2;
- }
- ?>
-
- bad.php:
- <?php
- $array = array();
- $i = 0;
- while(++$i < 1000){
- $array[good] = 2;
- }
- ?>
分别看运行时间(多次平均时间):
加引号的:
XML/HTML代码
- $ time php -f good.php
-
- real 0m0.013s
- user 0m0.005s
- sys 0m0.007s
不加引号的:
XML/HTML代码
- $ time php -f bad.php
-
- PHP Notice: Use of undefined constant bad - assumed 'bad' in /home/huixinchen/tmp/bad.php on line
- (此处省略999行NOTICE)
- real 0m0.100s
- user 0m0.020s
- sys 0m0.029s
看看,差别有多大?
哦, 或许我们应该模拟一下那些”幸运的”人们的情况, 去掉花费在记录NOTICE的开销, 看看~
XML/HTML代码
- $ time php -f bad.php
-
- real 0m0.037s
- user 0m0.018s
- sys 0m0.018s
我们可以看出, 基本上, 使用引号,和不使用引号的效率损失在3倍以上
那么, 这些效率损失到哪里去了呢?
我们分别看下, 俩个文件生成的OPCODE序列:
good.php :
C++代码
- filename: /home/huixinchen/tmp/good.php
- compiled vars: !0 = $array, !1 = $i
- line # op fetch ext return operands
- -------------------------------------------------------------------------------
- 2 0 INIT_ARRAY ~0
- 1 ASSIGN !0, ~0
- 3 2 ASSIGN !1, 0
- 4 3 PRE_INC $3 !1
- 4 IS_SMALLER ~4 $3, 1000
- 5 JMPZ ~4, ->9
- 5 6 ZEND_ASSIGN_DIM !0, 'good'
- 7 ZEND_OP_DATA 2, $6
- 6 8 JMP ->3
- 8 9 RETURN 1
- 10* ZEND_HANDLE_EXCEPTION
bad.php :
C++代码
- filename: /home/huixinchen/tmp/bad.php
- compiled vars: !0 = $array, !1 = $i
- line # op fetch ext return operands
- -------------------------------------------------------------------------------
- 2 0 INIT_ARRAY ~0
- 1 ASSIGN !0, ~0
- 3 2 ASSIGN !1, 0
- 4 3 PRE_INC $3 !1
- 4 IS_SMALLER ~4 $3, 1000
- 5 JMPZ ~4, ->10
- 5 6 FETCH_CONSTANT ~5 'bad'
- 7 ZEND_ASSIGN_DIM !0, ~5
- 8 ZEND_OP_DATA 2, $7
- 6 9 JMP ->3
- 8 10 RETURN
我们可以看出(其实,根据NOTICE的提示也知道), PHP会把没有引号引起来的键名当作是常量去获取, 当找不到的时候, 抛出一个NOTICE, 然后再根据”常量明”生成一个字符串, 然后再讲这个字符串做为键名继续~
聪明的你一定会想到, 可能会出现如下不可预期的错误:
PHP代码
- define('key_name' , 'laruence');
- ....
-
- $array[key_name] = 2;
-
明白了么? 数组中的非数字键的键名一定要有引号啊~
哦, 还记得有人会说, 那在字符串变量替换的时候, 写引号会导致错误,
恩, 标准写法:
PHP代码
- $string = "variable value is {$array['key']}"
我很赞同:”be lazy”, 但是, lazy也是应该有原则的.
最后, 好的代码,不应该通过关闭error_reporting来伪装.
附注, FETCH_CONSTANT OPCODE中找不到常量的相关逻辑:
C++代码
- ....
- if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
- zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
- opline->op2.u.constant.value.str.val,
- opline->op2.u.constant.value.str.val);
- EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
- zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
- }
- ....
——EOF——
膘叔最受不了的,就是discuz,特别是模版中的变量,全部是不含单引号的。写起来是方便啊。但是性能不敢恭维。所以common.inc.php的前面几句就是error_reporting了。。隐藏掉,看你怎么办,有本事你咬我呀。。
我还能怎么办?
Tags: 风雪之隅, 细节
PHP | 评论:1
| 阅读:22813
Submitted by gouki on 2009, April 22, 9:36 AM
HTML重构,以前是一个新鲜的东西,我也没有理解,博客园上有人在介绍,还写了三篇。。。
我这里只简单的复制点东西,还是以链接为重吧。(战略篇全文如下)
《Refactoring HTML: Improving the Design of Existing Web Applications》是一本精彩的HTML重构指南,作者给出了HTML重构的实践路线和方法。本文是《Refactoring HTML》的读书笔记,按照我的理解将全书的分为:战略篇,战术篇,工具篇。
本文是战略篇:全局方略的角度介绍重构的内涵,原因,时机,目标
嗯哼,我们开始:
进行重构就像打一场仗,而战争的发起是要慎重考虑的,《孙子兵法》里面讲“兵者,国之大事,死生之地,存亡之道,不可不察也。”所以动手重构之前首先要回答下面几个问题:
- 什么是重构?
- 为什么进行HTML重构?
- 什么时候进行HTML重构?
- HTML重构的目标是什么?
- 面对质疑:还要重构么?
什么是重构 Refactoring?
本书侧重实战,没有《UML Distilled》那样高屋建瓴的抽象,即使有抽象,抽象层面牵扯的细节过多(这一点在后续的阅读中也可以发现)。这一部分内容我援引了《Refactoring: Improving the Design of Existing Code》对重构的定义:
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior.
为什么进行HTML重构?
抽象地讲,HTML重构的可以让代码更能适应变化,应对系统和领域需求为新功能的开发提供更优秀的基础。
具体地讲,HTML重构可以:
- 让代码更具有可读性,更容易理解
- 重构过程中往往有意外的收获:发现隐藏的系统Bug
- 增强页面可用性, 关注点从设计者开发者转移到使用者
- 缩短提高页面的呈现时间(Slow pages -Rendering Times)
- 解决页面浏览器不兼容问题
- 搜索引擎优化Search Engine Optimization
进行HTML重构的时机?
- 每一次进行重新设计之前;新功能将构建在一个更稳固的基础之上
- Refactor When You Need to Fix a Bug
- Refactor As You Do a Code Review
- 一个原则:勿以善小而不为;重构的过程往往是断断续续的,很少有一个连续的时间给我们进行重构。所以我们只要有机会进行重构,就动手去做吧
HTML重构的目标(What Refactor To) ?
- XHTML
理由:XHTML更加严格,浏览器不再解析乱作一团的标签而是格式规范的页内容,这时负担从浏览器转移到页面开发者。内容聚合,搜索引擎优化,样式表都可以更好的应用基础。开发者能够更容易调试和解决问题,因为问题更容易定位了。XHTML不能完全解决浏览器兼容问题,但是它能够消除大部分的浏览器不兼容问题已经居功甚伟。主流HTML编辑器都提供对XHTML的支持。XHTML是未来Web应用提供坚实的基础,如:MathXML MusicXML SVG。
- CSS
理由:将展现层从内容中分离出来。为不同的阅读者提供高可读性。减少代码重复,节省带宽。
REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST提出了一些设计概念和准则:
1.网络上的所有事物都被抽象为资源(resource);
2.每个资源对应一个唯一的资源标识(resource identifier);
3.通过通用的连接器接口(generic connector interface)对资源进行操作;
4.对资源的各种操作不会改变资源标识;
5.所有的操作都是无状态的(stateless)。
REST之所以能够提高系统的可伸缩性,是因为它强制所有操作都是stateless的,这样就没有context的约束,如果要做分布式、做集群,就不需要考虑context的问题了。同时,它令系统可以有效地使用pool。REST对性能的另一个提升来自其对client和server任务的分配:server只负责提供resource以及操作resource的服务,而client要根据resource中的data和representation自己做render。这就减少了服务器的开销。
重构的目标不是金科玉律,你没有必要逐一进行实践。你可以按照XHTML->CSS-->Rest的顺序按部就班步步为营,也可以根据实际情况调整重构目标和计划。但是只要你做了,你就可以从重构过程中得到好处。
面对质疑:还要重构么?
重构的本质决定了它不是生产性的,重构的完成并没有新功能的产生。所以重构往往面临来自各方面的质疑:
面对质疑我们给出这样的答案:
- HTML重构从长远来看为后续开发提供了一个良好的基础,实际上是节省了时间。因为系统更容易添加新功能,更容易维护。重构的过程能让开发者对以前的工作有一个思考,对新人是一个熟悉系统的机会。
- HTML重构本身并不会占用太多的时间,因为我们有很多自动化的工具可用。
- HTML重构不需要一个连续的时间,断断续续的时间未尝不可,对于开发者来说,进行重构就像日行一善。
HTML重构:战略篇
HTML重构:战术篇
HTML重构:工具篇
Tags: html, 重构
PHP | 评论:3
| 阅读:22788