存档

作者存档

单件模式:Singleton那些事

2010年3月1日 3 条评论

单件模式确保一个类只有一个实例,并提供一个全局的访问点。 –《Head First 设计模式》

有些时候,我们恰好需要这样一种设计,保证我们实例化的类在进程地址空间内只有一个实例,有了Singleton,一切似乎都简单明了,其实暗藏杀机。

1. C++实现Singleton模式简单示例

简单的C++实现示例代码

class Singleton {
    public:
        static Singleton* GetInstance(void) {
            if (Singleton::m_instance == NULL) {
                Singleton::m_instance = new Singleton();
            }
            return Singleton::m_instance;
        }
    private:
        static Singleton* m_instance;
        Singleton() {}
};

使用gtest测试,简单地测试一下每次调用GetInstance是否返回同一地址

#include 
#include 

#include 
using namespace std;
#define NEW_COUNT 4096

class Singleton {
    public:
        static Singleton* GetInstance(void) {
            if (Singleton::m_instance == NULL) {
                Singleton::m_instance = new Singleton();
            }
            return Singleton::m_instance;
        }
    private:
        static Singleton* m_instance;
        Singleton() {}
};

Singleton* Singleton::m_instance = NULL;

TEST(Singleton, sample) {
    Singleton* init_instance = Singleton::GetInstance();
    ASSERT_NE(init_instance, (Singleton*)NULL);

    Singleton* p = NULL;
    ASSERT_EQ(p, (Singleton*)NULL);

    for (int i = 0; i < NEW_COUNT; ++i) {
        p = Singleton::GetInstance();
        ASSERT_EQ(init_instance, p);
    }
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

测试结果显示没有问题:
$ ./singleton
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Singleton
[ RUN ] Singleton.sample
[ OK ] Singleton.sample (1 ms)
[----------] 1 test from Singleton (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (2 ms total)
[ PASSED ] 1 test.

当然,这种测试没有太大意义。给出测试结果,主要用于之后的对比。

2. python程序中调用Singleton模式的C++代码
初次接触Singleton后发现,使用Singleton模式的C++代码融合到python中有意想不到的惊喜:如果有某个类初始化需要很长时间,而之后调用的速度都很快的话,使用Singleton模式,然后在python中多次调用时,不会出现重复的初始化操作。
简单地尝试了一下

首先在singleton.cpp中添加了一行输出,标识一次初始化操作:

Singleton* Singleton::GetInstance(void) {
    if (Singleton::m_instance == NULL) {
        Singleton::m_instance = new Singleton();
        std::cout << "initialize here." << std::endl;
    }
    return Singleton::m_instance;
}

封装的代码如下
$ cat _pysingleton.cpp -n

#include 

#include "singleton.h"

using namespace std;

PyObject * GetInstance(PyObject *self, PyObject *args) {
    Singleton::GetInstance();
    return Py_BuildValue("s", NULL);
}

static PyMethodDef _pysingletonMethods[] = {
    {"GetInstance", GetInstance, METH_VARARGS, "get instance."},
    {NULL, NULL},
};

PyMODINIT_FUNC init_pysingleton(void) {
    PyObject * m;
    m = Py_InitModule("_pysingleton", _pysingletonMethods);
}

编译出来共享库_pysingleton.so
$ cat Makefile -n

CC                =       g++
FLAGS           =       -ggdb -O2 -Wall
INC               =       -I/usr/include/python2.5
LIB               =       -lgtest -lpython2.5
LLIB              =

%.o:%.cpp
        $(CC) $(FLAGS) $(INC) -c $<

_pysingleton.so: singleton.o _pysingleton.o
        $(CC) -shared $(CFLAGS) $(LLIB) $(INCLUDE) $^ -o $@

clean:
        rm -f *.so
        rm -f *.o
        rm -f *.pyc
        rm -f singleton

写个简单的python脚本测试一下在单一进程空间里,是否真的只调用一次
$ cat pysingleton.py -n

#!/usr/bin/env python
# -*- coding: utf-8 -*-

''' sample for pysingleton
'''

import os
import sys
import _pysingleton

class PySingleton:
    def __init__(self):
        _pysingleton.GetInstance()

def main():
    ''' main function
    '''
    for i in xrange(3):
        PySingleton()
    print 'Done'

if __name__ == '__main__':
    main()

结果是
$ ./pysingleton.py
initialize here.
Done

3. 多线程中使用Singleton模式
多线程里就会遇到一个double-check问题 (double-check-lock problem, DCLP)
首先,静态变量m_instance作用域是全局的,处于临界区,在多线程需要加锁。这一点很好理解。
但是,简单的在if外面加锁势必会影响性能,毕竟只有第一次调用才会生效,每次都有一次锁操作太费时,也没必要。
于是,就会有double-check方法了,伪代码为
if (Singleton::m_instance == NULL) // first check
lock
if (Singleton::m_instance == NULL) // second check

从这里可以看出,double-check有效地避免了重复锁操作问题。
然而,问题还没有结束。采用double-check的话,又会引入另一个问题。在这里
Singleton::m_instance = new Singleton();
编译器可能会做个优化,首先将一个有效的内存地址返回给m_instance,然后再调用构造函数初始化。这样很有下一次double-check中首次检查通过,但是得到的内存地址指向的是一个未经初始化的类。后果怎么样,只有天知道了。
更多细节,参考这里:http://www.ibm.com/developerworks/library/j-dcl.html

a. 最简单的修改方法是
Singleton* temp = new Singleton();
m_instance = temp;

但是一个自作聪明地编译器还是会把结果优化成难以想象的样子
b. 另一个方法就是使用volatile关键字,用以声明不受编译器优化的影响
比如 Singleton* volatile temp = new Singleton();
但是远远不够,temp是volatile,但是*temp呢,temp->foo,temp->bar...这些成员呢?所以,要改的话,得把全世界都改成volatile,除了那个lock-_-|||

4. 以上都只考虑单核,再考虑一下多核机器,问题将会更加复杂

总结:珍爱生命,远离Singleton。尤其是不要把Singleton放进通用库中,还有C++中那个叫template的高级玩意儿,都搞在一起老天都很难保证会发生些什么。


1. 这里也在讨论单例模式Why Singletons Are Controversial
2. 代码托管到Google Code,欢迎围观、讨论、批评、挑bug:点此进入(http://code.google.com/p/zldemo/source/browse/#svn/trunk/blog/singleton_everything)
(墙内用户请不要使用https访问)

从今天起努力做个客观的人

2010年2月3日 4 条评论

在网上流传着这样一句话:“把思考交给了电视,把联系交给了手机,把恋爱交给了网络,把双脚交给了汽车,把健康交给了药丸”。

把思考从媒体中夺取过来,反而使得我们更加客观。人云亦云,信息过载。面对大量信息的介入,我们也会思考,但会思考得很冲动,不知不觉主观上也会偏离正确的方向。冲动消费只会浪费金钱,冲动思考则会浪费智商。任何媒体,无论是电视、报纸还是网络,从来都不是客观的。大量吸收这些信息,而不加深入思考和判断,只会让我陷入别人的思维陷阱中。

媒介影响我们思想的一个典型例子就是”80后”这个词。从某个”阴谋家”创造”80后”这个词之后,太多的人受到了相关的误导。而作为”80后”的我们又会怎么看呢?其实每个人心里都会有些自己的看法。相比那些”阴谋家”眼中”80后”的弱智行为,堕落状态,”80前”又能好的到哪里去呢?文化大革命中摧残人性的某些人,应该是一大群人,相比”80后”,不会感到汗颜吗?历史永远在进步,有理由相信新一代人整体上是会超越前一代人的。同样,我们也应当相信今天”脑残”、”弱智”、”不思进取”的”90后”将会超越我们尴尬的”80后”一代。历史将会用时间来证明这一点。

回到主题,无论是”堕落的80后”,还是”脑残的90后”,都是被动接受的误导。客观的看待问题,不是一味的获取外界信息,更要有独立自主的思想。靠大量信息作为训练样本,基于统计方法得出结论,那是机器人。人,当有信仰,有独立的判断能力,而不受外界因素干扰。

所以,我决定:从今天起,努力做一个客观的人。

补充:

罗马不是一天建成的,习惯的改变需要不断的总结和改进,记录下来后经常反省和查看都是必须的。推荐Evernote软件,方便在便携设备上查看,同时也非常适合多平台间信息同步。比如”2009年个人总结“,我就同步到itouch上的evernote中,上厕所时就看看…

分类: Lifestyles, 生活 标签:

Windows下文件搜索软件:Search Everything介绍

2010年1月19日 没有评论

以下是百度百科的介绍

Search Everything是速度最快的文件搜索软件。百G盘几十万个文件,可以在几秒钟之内完成索引;文件名搜索瞬间呈现结果。支持中文,支持正则表达式,可以通过HTTP或FTP分享搜索结  果。如果不满意Windows自带的搜索工具、Total Commander的搜索、Google 桌面搜索或搜索,如果正在使用或放弃了Locate32,都值得推荐这款体积小巧、免安装、免费、速度极快的文件搜索工具。

Search Everything 截图

Search Everything 截图

最喜欢的几大特点

  1. 体积小
  2. 速度快
  3. 支持正则匹配等复杂搜索条件
  4. 实时更新(安装软件比较明显:能实时看到新增加的文件)
  5. 支持远程部署(http/ftp等方式)

对我来说不算致命的几个限制

  1. 仅支持NTFS格式的硬盘分区
  2. 仅支持文件名搜索

在windows vista/win7中都会有受限于UAC,每次启动时都会弹出提示框。取消UAC自然不合适,Search Everything官网的FAQ已经给出了解决办法:Make Vista launch UAC restricted programs at startup with Task Scheduler
基本思想是:把Search Everything配置到计划任务里,每次系统启动时自动打开Search Everything,最关键的一点是计划任务中可以设置“以最高权限运行”。
具体步骤可以参考上述网址,该网页中步骤极其详细,其实只有简单的几步而已。

我的配置如下

  1. 创建计划任务

    第一步 创建任务

    第一步 创建任务

  2. 简单设置计划任务名称等信息。关键是设置“以最高权限执行” 计划任务

    第二步 设置计划任务,关键是“以最高权限运行”

    第二步 设置计划任务,关键是“以最高权限运行”

  3. 创建触发器,选择系统启动时触发操作

    第三步 创建触发器

    第三步 创建触发器

  4. 设定操作:启动程序Search Everything

    第四步 设置操作

    第四步 设置操作

Blog大事记

2010年1月19日 没有评论

随手记备忘录是个好习惯,呵呵。

  • 2010年1月,Blog迁移到Linode VPS上,彻底解决了古董机的mysql、apache、ip不稳定的问题:Blog使用美帝VPS:Linode服务介绍
  • 2009年8月15日,水木上淘到一个p3 CPU的古董机,100大洋(RMB),并开始运行Blog
  • 程序,ADSL环境。该古董配置:GenuineIntel Pentium III (Katmai) 501.159MHz/3个内存条共386M/8G硬盘。系统是Debian etch,linux 2.6.28。运行Blog服务使用的是apache2/php5/mysql5/wordpress2.8。

  • 2006年3月,开始写Blog,貌似是在hitidea.org上: zealot.hitidea.org。该博客服务由Berg童鞋提供,并友情支持了域名绑定。


此文不间断更新中……

分类: Blog历程 标签: ,

Blog使用美帝VPS:Linode服务介绍

2010年1月19日 5 条评论

写在前面:首先强调,这不是话题广告。刚换掉了古董机,算是鸟枪换大炮吧,总结后庆祝一下。

linode.com logo

linode.com logo

突然购买Linode.com服务,直接原因是一时头脑发热。根本原因是ADSL里放Blog太不靠谱了,ip经常更换,因此,需要时不时的更新DNS解析(DNS重新解析不会立即生效,慢则需要好几个小时)。观察了一周,服务、速度、稳定性都非常不错。

换用Linode后Google Analytics中的change项终于变绿了:

Blog rate in Google Analytics

Blog rate in Google Analytics

在家里ADSL环境下使用古董机就是这样浪费生命的

  1. 话说以前Blog是架在这样一台100大洋(RMB)的古董机上:GenuineIntel Pentium III (Katmai) 501.159MHz/3个内存条共386M/8G硬盘/Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+/VGA compatible controller: Matrox Graphics, Inc. MGA G400/G450。系统是Debian etch,linux 2.6.28。
  2. 运行Blog服务使用的是apache2/php5/mysql5/wordpress2.8,瓶颈在CPU上,一次请求apache占用CPU就超过60%。试探性使用nginx,这才发现需要配置factcgi,可耻地失败鸟。
  3. Mysql平均每个月挂掉2次,好在每次mysql check/repair都顺利的修复了。即使没有mysql crash,备份也还是很必要的。第一次crash后我就加了简单的自动备份脚本,每天凌晨自动备份,最多保留9份拷贝。
  4. 由于家里上网时ADSL,ip时常被更换,所以得记录ip,方便随时随地远程访问。在Google App Engine上起个服务记录访问ip,过滤掉公司的ip。家里的台式机上每隔一分钟访问一下这个ip。每次ip变换后就手动修改blog域名的dns解析。Dns解析开放api访问就好了。

鉴于上述种种不可饶恕的浪费时间行为,忍痛买了国外的vps。而且以后配置wordpress上twitter插件也很容易了。选Linode很偶然,上网看见@Fenng的Blog使用这个,应该不会太烂,价格也可以接受。这里也有一个推荐,介绍也很详细:http://www.blogkid.net/linode

注册Linode非常简单,特别注意的是亚洲访问速度较快的data center是旧金山的Fremont ,不要选错了。不过即使错了,也不用担心,我就选错了。在support页面咨询了一下客服,一顿饭功夫人家就帮忙换了个data center,自己只需要按照说明点三个按钮:关机、迁移、重启。

Blog迁移异常顺利,不到1小时完成了所有工作。系统选用Debian 5.0,候选系统也超多。LAMP安装工具使用apt,参考这里:“How To Set Up A Ubuntu/Debian LAMP Server”。

使用国外vps,最大好处是配置twiter插件,搭建某推的api都非常容易。以前用自己的台式机时,每次都想方设法修改代码,强制使用tor代理,而且速度贼慢。

现在空间、带宽冗余很多,有空整点好玩的东西,呵呵。
AD:需要注册的话,可以点这个推广的refer链接:http://www.linode.com/?r=2e236898b83cd7963f1cb6136e7b00cb9f13d1d8,按照说明应该会给我返利。

Btw:最后跑题说另一个使用虚拟化服务的case,twitter架构中考虑突发事件带来的访问洪峰问题时,购买了云计算服务。好处是避免了自行购买的设备长期闲置,导致浪费。Linode同样可以按需购买相应服务,升降级都很方便。

补充:使用的Linode 360配置如下

  • RAM: 360MB
  • Storage: 16GB
  • Transfer: 220GB

2009年个人总结

2009年12月31日 6 条评论

2009年最成功、最重要的事
想好了奋斗的方向:专心研究技术,踏实地做好基础技能学习(学和习)。

对比过去
踏踏实实做事真的很难,也是很多年轻人被抱怨的一个很大因素,而我更是如此。摒弃浮躁,踏实做事,该来的总会来。

2009年发生了什么
重新提起对数学和英语的兴趣,并开始系统的学习。除此之外,发现了很多问题,并独立思考解决方案。当然,方案和想法不是想出来,更多是在学习中去挖掘。过去一年中从各种途径获取了推荐的非常不错的书籍以及其他信息,并从中学习到很多知识,关于软件项目、个人管理、编程技能……
关于工作,2009年公司被收购,总体来说一切都在往好的方向发展,准确来说是转变。努力尝试从一个旁观者姿态来看的话,发现一路过来跌宕起伏,一次次的转变都静悄悄地降临在自己身上,乍一看不可思议,却也非常自然去走过来,感觉很奇妙。
关于感情,过去一年和亲友交流少了些。有些东西一旦放松就有可能逐渐远去,真的在乎就不能回避,甚至忽视。不过,上半年被QQ、MSN、GTalk、校内等社交网络中无关信息打扰地太严重了,2010年得认真解决这个问题。感谢那些却始终惦记着我的人。
2009也是一个令人失望的一年,眼睁睁看着这个国家的文明一次次倒退,却无能为力。能做的只是顺着众网民的大流:微动力,广天下。

2009年最兴奋的事
看见好书,立马上网下订单,而不用像上学时那样苦苦纠结。不过,现在书累计重量接近我的小冰箱了,下次搬家将会很郁闷。

2010年目标
1. 学习和提高
a) 数学和英语,这两个都是基础,目前已经开始实施,按部就班,按需微调,暂时不需目标来指导。尽量做到平均每周能有4天中独立出一段有价值的时间来学习数学和英语。
b) 编程经验,感觉过去一年看了太多的书,写的代码相对来说却不够。不过,按照提交的工作计划,2010年将会极大改善,我个人很期待。当然,09年积累下来的知识,包括个人管理经验,以及对软件项目认识的加深等,将会非常有益于将来的工作安排,不至于总是被计划外的事情和意外折腾地措手不及。
c) 调整好作息,善待自己。今年对厨艺稍微研究了一阵子,已经能自己带饭上班了。在这个只有母乳相对来说比较安全的国家,安全饮食根本不现实,只希望自己能尽力做到最好吧,没有什么比健康更重要了。
2. 改进和突破点
a) 多与亲友交流。除了编程,还有很多事情能让生活变得有趣,不要让任何一个理由抢占了分享的乐趣。
b) 多锻炼,小区跑步的人不少,天气好些时,可以尝试开始锻炼,并养成1个习惯用于健身(骑自行车上班不算)。
c) 至少参加1次公益活动,内容不限。
d) 至少养成1个好习惯,除之前提及的不算,内容不限,可以是工作管理、作息规范、锻炼等。
3. 重复一点:善于休息。
一句话感想:有啥也别有病,没啥也别没精神。

p.s. 2010怎么发音

How Are We Going To Say “2010″

How Are We Going To Say “2010″

图片来自:http://tc50tweets.techcrunch.com/story/396885318/how-are-we-going-to-say-%E2%80%9C2010%E2%80%B3-a-website-comes-just-in-the-nick-of-time

分类: GTD, Review 标签: , ,

工作邮件处理技巧 – Outlook

2009年12月26日 没有评论
outlook 2007

outlook 2007

本文主要针对outlook,不是因为outlook多么强大,而是很多公司考虑到保密问题都会自己建立邮件服务器。并且,公司内沟通经常使用约会、会议邀请等功能,也只有采用outlook那一大坨东西。
Outlook最大的麻烦就一个字:慢。用过outlook的人都应该有所体会。想要改善outlook速度只有一个办法:删掉所有的邮件。真的,删掉,全部删掉。一年前看到outlook数据文件达到400多兆时,我就毫不犹豫的选择了这个方法。后来,删掉这些邮件确实没有什么不好的影响。
日常管理时,尽量做到每收一封邮件就删掉。即使保留部分邮件,也应该控制保存时间尽量不要超过一周。
删掉后那些信息上哪找去?每一封邮件都有不同信息,需要放到不同地方,但绝对不应该原封不动地躺在收件箱里。
1)    通知公告类,看完就删
2)    垃圾邮件,删除
3)    需要确认某项操作的,回复,删除。
4)    报警、出错信息,加入todo,删除。
5)    有任务分配的邮件,加入todo,删除。
6)    邮件内容超长,标记未读,有时间再看;看完后,删除。(更好的方案是,转存到手机上,然后删除。我用的是evernote,直接集成到outlook中,不到1秒钟就可以完成转存工作)
7)    有重要信息,比如合作方联系方式(多在签名档中)。存到wiki,然后删除。这样做好处很多,首先,累积的邮件会使outlook变得极其臃肿,速度会大幅下降;其次,wiki很方便地与同事共享;最后,也是最重要一点,你离职的话需多久时间整理这些信息?事实上,离职后都会忘了处理这些信息。我就经历过这种痛苦,接手某项工作后,很多一部分精力都在查找各合作方的联系方式、以及相关的合作文档。
8)    其他,尽量删除吧。
关于存档,用outlook管理的话不推荐使用存档,存档会让你的outlook慢如蜗牛。我采用的方法是,笔记本上处理完邮件后立即删除。在公司的台式机上接受所有邮件,但不做任何处理,必要时会查询。事实上,基本上一个月也很难查1、2次。(只有一台电脑的话可以再启用另一个简单、便于查询的邮件工具来备份所有邮件,比如foxmail)

参考资料:
1)    这本书中有专门章节来讨论邮件处理技巧:《时间管理—给系统管理员》,http://www.douban.com/subject/2253513/。
2)    Zenhabits也有专门的讨论,可以参考,基本上思想差不多:http://zenhabits.net/2007/01/email-zen-clear-out-your-inbox/

1) Don’t check email first thing in the morning, or have it constantly on. This is a tip offered by many blogs, so nothing new here. Checking email first thing will get you stuck in email for awhile. Instead, do your most important thing for the day, or the thing you’ve been procrastinating on the most. Then check email. Better yet, do 2 or 3 things first. Also, if you are constantly checking email throughout the day, or it notifies you as soon as an email comes in, you will be constantly distracted and not able to focus on the task before you. I check once an hour, but you might have different needs.
2) When you check your email, dispose of each one, one at a time, right away. Make a decision on what needs to be done on each email.
2a) Is it junk or some forwarded email? Trash it immediately.
2b) Is it a long email that you just need to read for information? File it in a Read folder (or tag it Read and archive) or print it to read on the road (while waiting in line, for example).
2c) If the email requires action, make a note of the action on your to-do or GTD lists to do later. Also note to check the email for info if necessary. Then archive the email. You can easily find it later when you need to do that task.
2d) If you can respond to it in a minute or two, do so immediately. Don’t put it off. If you wait, you’ll end up with a backlog of emails to respond to, and you may never get around to it. I respond quickly, with a short note, and send it right away. That way I’m viewed as responsive and on top of things.
2e) If you need to follow up on the email later, or are waiting for a response, note it on a Waiting For list. Don’t just leave it in your inbox as a reminder.
3) I have only one folder: Archive. When I respond to an email, or finish reading it if it doesn’t need response, or note it on my to-do list, I archive it. Simple as that. You could add a Read folder if you want. I usually print longer ones to read later, like during lunch or while waiting for something. Other people have an Action folder or a Waiting For folder, but I find that that’s just an additional inbox (or “bucket” as GTD’s David Allen calls it) that you have to constantly check. I don’t like to check extra folders. I have my to-do lists and my Waiting For list, and that’s good enough. So it’s as simple as pressing “Archive” on an email, and if I need to find it later, Gmail’s search is so good that it’s easy to find. I’ve never had any problems with this system.
Email Zen is that easy: check email at regular periods, take action on each email right away (or note it on a list to do later) and archive.

分类: Get Things Done, GTD 标签: , , , ,

Blog改用微软雅黑字体

2009年11月10日 1 条评论

一般网站都不会特意设置花哨的字体,但是个人Blog使用自己喜欢的字体还是没问题的。微软雅黑确实比较好看,最近也看到不少Blog使用了该字体,跟风一下,修改了style.css。顺便把字体稍微调大了一点,一直觉得字有点小,总算是改过来了:

23 font-size:14px;
24 font-family: 'Microsoft Yahei', Verdana, Arial,"BitStream vera Sans",Tahoma,Helvetica, Sans-Serif;

27 line-height: 160%;

修改后的效果

Blog使用微软雅黑字体的效果

Blog使用微软雅黑字体的效果

分类: Blog历程 标签: , ,

过度设计的典范: 新浪微博

2009年11月7日 没有评论

(我的登录名是chzealot[at]gmail.com)
以下功能除非特别说明,都是在win7下Maxthon中测试(IE v8)
1. 登录框的suggestion
首先,suggestion是为用户提供便利的,而且可以把记忆的负担从用户那里接手过来。但是新浪微博这个suggestion的目的我一直没看明白。很显然我的登录名排在suggestion的倒数第二,而排在前面的那些候选项中除了第一个外其他都不是有效的微博帐号。不知道新浪pm怎么想的,用一堆无效的登录名霸占了原本属于有效用户名的位置。可见这个suggestion要么就是拍脑袋拍出来的,要么就是pm能力有问题。
其次,有一个非功能性的bug,suggestion框与登录名的框没有对齐,大概有3个像素的差距。做出花哨的功能远没有查找细节的bug来的重要,显然在国内测试的重要性总是被人忽略(后面还会列出很多bug)。
最后,又是一个过度设计的问题,看看下图中的鼠标右下方,那个chzealot@sina.com的提示干啥用的?没有任何提示作用,反而遮住了第三个候选项。该设计的地方不去动脑筋想,却把精力投放在毫无意义的事情上。把最简单的事情做好就是基础,基础没做好就想往上盖房子只能苦了IT民工加班做无用功。

login suggestion

login suggestion

2. 登录框上提示输入密码的框
首先,没有与输入框对齐。
其次,也是最重要的一个bug,为什么“请输入密码”的提示框飘在登录名的输入框上方,难道让我在第一个输入框中输入密码吗?

提示:“请输入密码”

提示:“请输入密码”

3. 找回密码功能在chrome v4中无法使用
点击“找回密码”,进入http://login.sina.com.cn/cgi/getpwd/getpwd0.php?entry=sso,页面空白。
虽然chrome用户量少,可能不在考虑范围之内,但是这么简单的页面在chrome中显示为空白页在我看来太说不过去了。
4. 新浪微博不是微博
为什么呢?因为在新浪微博不是你在玩,而是你看别人玩,看名人玩,又是还要被新浪玩。看下图吧。
登录后就只能看到5条最新的消息,不知道是不是我笨,找了好半天也没找到怎么查看更多。从下图中,我只能感受到新浪大声呼喊:你丫赶紧去关注那些名人吃喝拉撒吧!

关注名人

关注名人

5. 搜索用户
这个输入框好复杂啊,搜完之后我才发现应该选择suggestion中第二个选项才能搜索人。
首先,搜索用户和搜索话题两个截然不同的东西硬塞在一起成何体统。
其次,这个suggestion的风格到处都在使用,给我留下的印象是候选项是具有相同属性和功能的并列元素,显然在这里不是。于是我刚学会用这个suggestion,不一会又迷糊了。简单啊,简单的在大部分情况下就是对的。
还有,校内网的右上角就是搜索用户,其他也有不少类似网站右上角用来搜索用户,为什么不遵守用户习惯呢。非得把搜索话题硬塞进来。
最后,那搜索话题放哪呢?这个一会就说。

搜索用户

搜索用户

6. 搜索话题
刚才说到了搜索用户功能兼了搜索话题功能,其实在同样页面上有个专门的话题搜索框,见下图。重复设计!
既然已经有了专门的话题搜索框,再把话题搜索塞到用户搜索里就难以接受了。简单啊,想法能不能简单点。

搜索话题

搜索话题

7. 我的好友在哪里
基本上所有社交网站都会在sidebar中给出好友列表,但是新浪微博没有。你只能在右侧看到“粉丝”,这个链接是你的好友,faint吧,兄弟们。
反而,新浪给出了大量与你无关的人,就是那些所谓的名人,其中大部人名人就是上来诉说自个的吃喝拉撒,毫无意义。

关注用户

关注用户

最后,总结一下,新浪blog就是名人写日记给粉丝看得,而且大部分名人的日记很流水很无聊。显然日记满足不了需求了,于是新浪推出微博,让这些名人上来把吃喝拉撒事情也能方便的给粉丝们交代了。
典型的小作坊作业,目光短浅,其实趁着twitter被盾,直接抄过来,多雇点编辑删帖,对上做好公关工作。做成中国的twitter后,总有一天那些所谓的名人自己就上来注册了,而且不会发无聊的东西,因为那时没人关注吃喝拉撒了。

wordpress不显示分类列表title的bug

2009年10月28日 2 条评论

刚才把菜单栏清理了一下,就剩下about页面。于是把inove的分类列表提到menu栏,右边的sidebar也缩短了不少。
但是立马出现了一个新问题,菜单中鼠标移过去会有title信息遮住二级菜单,按照文档说明修改后却没有生效,如图:

has category title

has category title


首先,查了一下wp_list_categories函数的用法:http://codex.wordpress.org/Template_Tags/wp_list_categories,按照文档里描述的,把use_desc_for_title参数设置为0就行:
wp_list_categories('title_li=0&orderby=name&show_count=0&use_desc_for_title=1');

use_desc_for_title
(boolean) Sets whether a category’s description is inserted into the title attribute of the links created (i.e. <a title=”<em>Category Description</em>” href=”…). The default is true (category descriptions will be inserted). Valid values:
1 (True) – Default
0 (False)

查看wp-includes/classes.php中wp_list_categories函数定义才发现有bug:

1331 if ( $use_desc_for_title == 0 || empty($category->description) )
1332 $link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $cat_name) . '"';
1333 else
1334 $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description',
$category->description, $category ) ) ) . '"';

很显然,不管use_desc_for_title参数是0还是1都会显示title信息,无语了,稍微改动一下:

1331 if ( $use_desc_for_title == 1 && empty($category->description) )
1332 $link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $cat_name) . '"';
1333 else if($use_desc_for_title == 1 && !empty($category->description))
1334 $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';

总算隐藏掉了分类列表的title信息了,如图

no category title

no category title