程序员的常识

之前参加了一次关于产品易用性的争论,焦点在于产品中一个文件传输过程既没有提示也没有进度,导致用户根本无法确定是否在传输。

一方认为开发组的程序员应该很容易的看到产品易用性的问题,就像传输文件的操作,有等待状态或者传输进度都是最普遍的做法,开发组竟然视而不见也没有意见反馈提出实在无法接受;另一方则认为让程序员决定这些界面实在有失偏颇,之所以出现这样的问题是由于产品经理没有将界面需求确认清楚导致的。

乍一看,很容易让人联想,这是程序员缺乏责任心或者产品经理缺乏责任心导致的。但真的只是责任心的问题吗?我认为并非那么简单,更深层的问题出在开发体制上。

最近花了不少时间研究敏捷编程,其中提到自组织,提到程序员的常识。何谓常识?水太烫要等凉了再喝,这就是常识,因为大家都是这么做的。同样在软件开发方面,传输文件一定要有进度或状态的提示,这也是常识,也是因为大家都这么做。每个程序员都是从无数软件的使用中成长起来的,这种基本常识不可能没有,那么为什么会出现这么没有常识的结果呢?

还是喝水的例子,如果你的工作要求你在拿到水的时候,必须要用温度计确认温度在20度时,才能饮用。时间久了,当你拿到一杯水手边又没有温度计的时候,恐怕你就会不知所措了。

同样的问题也在软件开发过程中,传统的瀑布式的开发模式,是由上而下的,就像工业生产,上面做好了模具,下面倒上原料就好。在这样的体系下,程序员往往只担负一部分工作,需要严格按照任务分配行事,形成了让做什么做什么的习惯,于是就慢慢忘了自己还有程序员的常识。不思考,不比照,按部就班,这在完整的瀑布式开发中没有任何的问题,但实际上,很少有公司能做到真正完整的需求,真正完整地设计,于是文章开始的扯皮就出现。

程序员缺乏常识并非只对团队有影响,从程序员自身的角度来看,会思考,会对照,会主动创新,这才是程序员的核心价值。没有常识的人如何听够体现出自己的价值,没有程序员常识的人又如何能体现出自己作为程序员的价值呢?

Posted in 七嘴八舌 | Tagged , , | Leave a comment

吴太伯事件

史记世家第一记载了吴太伯的故事。

大致是讲周太王(就是推演八卦的那个周文王的爷爷)有3个儿子,其中老三最贤,儿子又是圣子姬昌(就是周文王),老大老二想让老三即位,就跑到南方蛮荒之地装野人。后来传到武王即位,伐商得了天下,为感激当年让位的恩情,特地跑到南方找那位大伯公和二伯公的后裔,谁知这两位魅力强,竟然同化了蛮族还建立了国家,武王也不好让人家举家搬离故土,就分封其中一支在原地也就是后来的吴国(被卧薪尝胆的勾践灭掉的国家),又封另一支到北方的虞,做了公爵。而让位的大伯公也被顺便追封,史称吴太伯。

这个让贤的故事很符合儒家一贯的思想,所以也被史记列为世家第一,在姜太公周公之前。但让人感觉未免太完美,就算吴太伯想让位也实在不必那么夸张的举动,即使在400多年后,吴国仍然被视为蛮夷之地,何况那个时候?

最早看到的质疑是柏杨的说法,柏杨以一贯的阴谋论调直接说这是夺嫡阴谋,吴太伯失败后被流放到吴国,并没有什么让贤佳话。但柏杨并没有给出支持他论点的史料。

最近看杨宽的先秦十讲也提到这个事情,说法却非常有趣。

杨宽认为,吴太伯事件实际是被儒家扭曲的本末倒置。吴太伯并非吴太伯而应该是虞太公。这话怎么说呢?原来在周太王时,周就已经开始图谋商的地盘,所以派出自己的大儿子(也就是所谓的吴太伯)跑到虞地(大概在晋南)建立前进基地。这步棋走实在是卓有成效,虞的势力曾一度扩张到商王狩猎之地,甚至后来武王克商也是完全依靠虞国的后勤补给。正因为虞国有大功,所以在定鼎分封时,特别封公爵(封公爵的除了拉拢商人的微子和武王的叔叔,就是虞,姜子牙和周公旦都不是)。而吴国一支则是在后期为压制南方蛮族而特意分封的,也正因此在克商时,并未提到有吴国的助力。

180度大逆转啊,不过貌似合情合理,但历史不容编造。于是,杨宽提出自己的依据,<穆天子传>的记录。

<穆天子传>记录了西周中兴王朝周穆王巡游西方和西王母在昆仑山饮宴的故事,一直以来被作为志怪小说看待。但近年的研究发现其中的记载和金文记载相吻合,所以又被逐步重视起来。杨宽认为,穆天子传最初是北方戎族的口传的历史,最初周穆王为北伐犬戎曾亲自探视北方,而当地的蛮族接待有功被封侯,于是蛮族就将当时的事情作为祖先的荣耀口口相传,直到战国时,魏国史官在地方上采风采到才成书的,其中内容并未受到儒家的扭曲,相对可信。

那儒家为什么要编造吴太伯这样的故事呢?古<书>中有《武成》一篇曾记载牧野之战流血飘橹的景象,孟老夫子看到了,认为武王克商是以至仁伐至不仁,怎么会那么残酷,于是就把这篇给删节了,还留下一句名言,尽信《书》不如无《书》。《武成》由此失传,现在只能在其他典籍中看到只字片语。由此推想开来,一个是礼让贤侄后世追封的吴太伯,一个是积心处虑要以臣叛君的虞太公;一个是兄弟礼让的佳话,一个理智分工传贤不传长的现实,当然是前者更合儒家的胃口了。

Posted in 读书礼记 | Tagged , , , | Leave a comment

说说东野圭吾

花了2天多一点的时间,看完了东野圭吾的《嫌疑人X的献身》和《放学后》

第一个感觉是非常流畅,尤其是《放学后》事无巨细缓缓的一一展开,虽然所有的线索情节都在前面埋好了,但由于交代的细致所以没有突出任何刻意,同时又不显得拖沓,这点很难得,总感觉日本人的说都比较啰嗦的。

其次是,总有颠覆性的推理,东野惯于给读者设定一个错误前提,然后再在这个条件进行各种不同条件的推断,自然这些推断都是忽悠读者的,最后一亮底牌,发现前面的所有推断都合理的,但前提都是错的,所以所有推断都落空了。

最后是,东野的这两部书都很残酷,为了把情节做的尽量的曲折,很多地方突破了一般人的认知底线,《嫌疑人X的献身》中的无奈和痛苦,《放学后》的美善下的丑恶,实在是破坏了很多美好的东西。

所以,两部书的结局都很简单,有点像是港片,boss被干掉,大家一欢呼就结局了(一如本文,说完了就晚了:)

P.S. 回头看了看,说的都很隐晦,尽量不剧透,看过了自然就理解了,呵呵

Posted in 读书礼记 | Tagged | 2 Comments

折腾:SSH

墙越建越高,所以打算搞个SSH代理做私人网络用

据说使用虚拟主机就可以,据说Godaddy就支持SSH,据说必须要Linux服务器

于是先把服务器升级成Linux,没想到控制面板里没有这个升级项,写信给Godaddy,回复因为有SQL Server的数据库,无法迁移导致

貌似那个数据库只是测试用了一下没啥重要数据,干掉。

终于可以迁移了,N小时的等待,完成。

进入发现允许SSH,必须要再次换主机,网上说必须要先备份数据库和网站数据,不过Goddady空间和数据库采用的不同数据库,所以多次迁移也无所谓,不过多次备份总是没错的。

备份,然后开启SSH,N小时等待,完成。

据说Tunnelier比MyEnTunnel,安装Tunnelier,登录SSH没有问题。浏览器使用Chrome+Switchy,找了N多教程,其实配置很简单,完成。

一切就绪,就是SSH没法用无法连接,换用MyEnTunnel,发现是服务器拒绝的,貌似是因为服务器没有开启转发导致。

继续Google,发现Godaddy有限制,貌似没有人这样搞成功。

那没办法了,发了邮件给Godaddy,估计也很难解决,没准还要考虑换主机,这折腾的。。。。。。

Posted in 折腾, 网站建设 | Tagged , | 2 Comments

折腾:清洗笔记本键盘

趁着过节把笔记本键盘全部拆开清洗了一下。

要说thinkpad做工的确不错,按键一个一个的一掰就开,用洗涤灵加水泡一下就不久干净了,在用吹风机风干。

键盘底盘有不少油渍,头发,纤维之类的东西,用棉签一一清理,没加水或酒精什么的东西,所以并不是完全的干净,不过已经强了不少。

最后是装,这个太麻烦了。

首先是键位,本来挺熟悉的按键一放到满是键位的底盘上马上傻眼,不知所谓,幸好拆前用相机留了底。

其次是键太多了,就算对照照片也是半天的繁忙- -

开机一用,发现左右Shift键装反了,原来以为两边是对称的,实际上右边的略大一点,只好重新掰开换过来。

最后,键盘焕然一新,原来有点不太灵的键敲起来也顺畅了,总算是没白折腾

Posted in 折腾 | Tagged , | Leave a comment

twiproxy – 基于GTAP 0.4的twitter API proxy

twitter终于封杀了basic auth,为了避免被拒之墙外,在Google Appengine上装了一个GTAP 0.4的版本,貌似Twitterrific可以用了,但Twitter的官方客户端还不能使用。

说起Twitter官方,那可是很纠结的一段。

最初还是tweetie的时候,特意买了一套,谁知不久twitter被封杀,tweetie不支持代理,等啊等,听说tweetie 2支持代理了,才发现之所以叫2原来是不能升级令要付钱的,嘿嘿,有点上当的感觉啊

后来,tweetie被twitter收购,变成官方,免费的客户端,高兴啊,赶快去下载,发现下的不能用,原来又升tweetie 3了,而tweetie 3只支持xAuth,比如GTAP这样的,只支持oAuth的也不能用。

没办法,偷懒不了,自己动手吧

说起xAuth,其实是oAuth的简单模式,和Basic Auth最大的不同是,不再传递用户名和密码,而是传递access_token和自签名数据,GTAP之所以不支持,是因为没有对oauth/access_token这条指令做支持。

所以,在GTAP上做了几处修改:

  • 添加oauth/access_token这条指令的处理,将客户端发送过来的用户名/密码转换成access_token和access_token_secret
  • 当客户端发送请求时,通过客户端发送的access_token获取access_token_secret。GTAP使用用户的密码对保存的access_token和access_token_secret进行加密,导致无法直接通过access_token获取access_token_secret,这本是安全机制,不过考虑到部署者完全可以通过log方式输出用户名密码或者token,所以改为明文存储。可能还有更好的办法,这里先偷个懒吧,反正一般都是自己部署的APP
  • 增加了basic命令,按说起来,通过代理是完全可以支持原有的Basic Auth的客户端的,比如Chrome著名的插件Metrist,通过basic可以实现这个,但目前的测试结果比较奇怪,数据已经正常返回了,但Metrist只有偶尔可以获取到,不知道为什么

为了开发方便,在Google Code上重新构建了一个项目twiproxy,采用和GTAP一样的开源协议,有兴趣的可以去看看,也欢迎提供修改建议:)

最后列一下twiproxy的功能

  • 支持原有GTAP 0.4的功能
  • 支持xAuth模式,即支持twitter for iPhone登录
  • 支持原有basic auth客户端(未确认)

地址:

  • twitter.com : xxx.appspot.com/
  • api.twitter.com : xxx.appspot.com/api
  • basic auth : xxx.appspot.com/basic
Posted in 我爱开源 | Tagged , , , | 9 Comments

姓,氏及其他 – 实验篇

之前写了《姓,氏及其他》,某日突发奇想,如果现在人改叫古代的名字会怎么样?

结果找了一帮人实验发现:

  1. 排行失效了,现在搞计划生育,盘算下来大家不是伯(孟)就是季,其他字基本用不上,所以名字好像都一样似的
  2. 没人有封地什么的,搞行业吧,认识的人多数都是计这个行业的,好,名字又一样了
  3. 像孟,季古代估计不是姓,现在都成姓了,叫孟孟,季季,蛮奇怪的,好在没人姓伯,要不就成伯伯了,囧
  4. 三字名的人麻烦了,加上行业,加上排行,加上名字,四个字了,怪

总之,时代变了,什么东西被丢弃掉的确是有原因的,所以就让它消逝在历史的长河中吧

Posted in 七嘴八舌 | Tagged , , | Leave a comment

CMake编译Qt

貌似有个CMake教程上说过“不要使用CMake编译Qt”,原因是Qt有自己的QMake,用CMake会费时费力,不过为了能把所有工程采用同样的编译方式,还是尝试了一下,的确很麻烦。

首先需要下载Qt SDK,因为打算用VS2010编译,所以下载了everywhere的4.7b2版本(注意:4.6.3不支持2010,强编会出错,4.7b2静态编译也会有同样的问题,估计正式版会有改善吧)

编译整体还是比较简单的

  1. 把VS目录下的vcvars32.bat复制到qt目录下
  2. 打开控制台,首先运行vcvars32.bat
  3. configure –platform win32-msvc2010
  4. nmake
  5. 等待N长时间编译完成,真的非常长时间
  6. 编译结果6G,保留bin,include,lib目录即可

4.7的编译有个缺点就是所有路径都是完整路径会写死,且不能选择编译结果的输出路径,所以要是打算多次编译一定要确定好目录,否则会很麻烦。

然后写一个简单的CMakeLists.txt文件:

#Project Name
PROJECT(BookStar)

SET(QT_FOLDER D:/qt-4.7.0-b2)

# include directories
INCLUDE_DIRECTORIES(inc
                    ${PROJECT_BINARY_DIR}
                    ${QT_FOLDER}/include)

# lib directories
LINK_DIRECTORIES(${QT_FOLDER}/lib) 

# source
SET(SRCS
    src/main.cpp
    src/mainwindow.cpp   
    ${MOCS}
)

# add exe
ADD_EXECUTABLE(BookStar ${SRCS})
TARGET_LINK_LIBRARIES( BookStar QtCore4 QtGui4 )

编译错误,原来Qt在编译时,需要首先使用uic.exe编译UI文件,通过moc.exe处理Q_OBJECT之类的宏,当然你可以去掉这些定义,否则就需要加上:

# COMPILE UIs
SET(UIS
    mainwindow
)

FOREACH (ui_file ${UIS})
    SET(TMP_IN "${PROJECT_SOURCE_DIR}/res/${ui_file}.ui")
    SET(TMP_OUT "${PROJECT_BINARY_DIR}/ui_${ui_file}.h")
    EXECUTE_PROCESS(COMMAND ${QT_FOLDER}/bin/uic.exe -o ${TMP_OUT} ${TMP_IN})
    MESSAGE(STATUS "EXEC=${QT_FOLDER}/bin/uic.exe -o ${PROJECT_BINARY_DIR}/ui_${ui_file}.h ${PROJECT_SOURCE_DIR}/res/${ui_file}.ui")
ENDFOREACH(ui_file)

# CREATE MOC
SET(HEADERS
    mainwindow
)

FOREACH (header_file ${HEADERS})
    SET(TMP_IN "${PROJECT_SOURCE_DIR}/inc/${header_file}.h")
    SET(TMP_OUT "${PROJECT_BINARY_DIR}/moc_${header_file}.cpp")
    EXECUTE_PROCESS(COMMAND ${QT_FOLDER}/bin/moc.exe -o ${TMP_OUT} ${TMP_IN})
    SET(MOCS ${MOCS} ${PROJECT_BINARY_DIR}/moc_${header_file}.cpp)
    MESSAGE(STATUS "EXEC=${QT_FOLDER}/bin/moc.exe -o ${PROJECT_BINARY_DIR}/moc_${header_file}.cpp  ${PROJECT_SOURCE_DIR}/inc/${header_file}.h")   
ENDFOREACH(header_file)

这里要注意的是:EXECUTE_PROCESS在COMMAND后面不能加引号,命令直接写,否则执行的程序也不会出错,但也不会正常运行,这个曾让我纠结很久- -

当然为了实现简单,两个列表变量定义时都没有带扩展名,如果希望更清楚一些,则需要通过CMAKE的字符串处理处理一下。

编译是没有问题了,但FindQt4还不能用,不知道是不是编译时没有安装好,每次都找不到Qt的目录,这个还需要继续研究

Posted in 软件技术 | Tagged , | Leave a comment

代理已升级

最近一直有传言说,8月底twitter要彻底废弃basic auth,改用Oauth,之前用的birdnet api proxy貌似没有对oauth进行更新只好废弃

本来打算用twip,可惜Godaddy的windows hosting不支持CURL,部署好了才发现,比较郁闷

改用GTAP 0.4,升级还比较顺利,不过使用和以前有了较大的区别

首先api路径,birdnet是xxx.appspot.com/api,而gtap是xxx.appspot.com

其次,使用前需要先登录xxx.appspot.com,并在twitter上验证(需要自备翻墙软件),验证后返回xxx.appspot.com,在new key的地方输入密码,可以和twitter密码不同

最后,在客户端更改api proxy地址和密码(即之前所输密码),即可正常使用

比较郁闷的是,twitter在iPhone上的官方版本无法验证成功,使用twitterrific可以正常收发,请之前使用代理的朋友自行更新使用。

原代理不再支持,即日生效。

注:暂时不方便更新的朋友也可以使用:2.latest.xxxx.appspot.com/api替代原有的api proxy地址,直到twitter屏蔽basic auth为止。

Posted in 生活啊生活 | Tagged , , | Leave a comment

姓,氏及其他

《史记 管蔡世家》有段话,列举了周武王(就是封神榜上伐纣的那位)兄弟十人:

(周)武王同母兄弟十人。。。长子曰伯邑考,次曰武王发,次曰管叔鲜,次曰周公旦,次曰蔡叔度,次曰曹叔振铎,次曰成叔武,次曰霍叔处,次曰康叔封,次曰厓季载。

要从现代人的角度看,估计要傻眼,同母兄弟不同姓啊,姓啥的都有,又说同母弟,估计武王这位老妈多次改嫁,不过十次这也未免太多了吧- -

但实际上,这里面的十位都是文王(武王的老爹演八卦那位)的儿子,说同母弟只是因为文王老婆很多,还有其他的孩子。而这十人其实都是同姓,都姓姬,那为啥会被称呼的千奇百怪呢?

要说起来,这还是先秦(秦朝以前)习惯,即男子称氏不称姓。

现在人姓氏不分家,姓就是氏,氏就是姓,可在先秦姓氏是不同的。

姓,即女生,指母亲这一支,据说是母系氏族时代的产物,当时人知母不知父,所以用姓区分,所以才有同姓不通婚的说法。母系氏族结束以后,财产土地都是父子世袭,于是就有了氏,氏用来标识男子地位,即家族,封地,官位,所在国等等。

比如在秦国变法的那位商鞅,在魏国学习时称公孙鞅,因为当时是平头老百姓,没有氏所以称姓;到了秦国闯出点名头,被称卫鞅,因为他是卫国人;被封商地,称商鞅,这个商字就是氏。

再如大名鼎鼎的鲁班,本名叫公输班,只是因为是鲁国人所以称鲁班。

这样的例子还有很多。在如舂秋五霸的齐桓公,叫姜小白,称齐小白。不过也有奇怪的人,那就是秦始皇,本来从赵国回来时,因为在赵国当过人质称赵政,后来改回本名嬴政,史称即嬴政,并没有称为秦政。

这里就要注意一个问题,之前一直说是先秦,称氏的习惯似乎到秦朝以后就没有了,为什么呢?关键是制度的变革,秦以前是分封制,大小诸侯的继承权是神圣不可侵犯的,所以标识家族就是标榜自己的身份地位,这和西方的徽章很类似。在西方,通过家族徽章就可以推断出这个家族的来源历史甚至封地财产。而在中国氏就是徽章。可秦立国以后,封建被消灭了,虽然汉朝又恢复了一部分,但只限于皇室,所以一般人再没有必要也没有办法通过氏来标榜自己了,所以姓又再次兴起直到现在也就不奇怪了。

当然不是人人都是贵族,没有地位的人一种如公孙鞅就称姓,也有某些人以特长称呼,如解牛的庖丁,并不是姓庖,只是因为职业是厨子才称庖丁,至于他姓什么,那就没准,赵钱孙李都有可能。其他还有奕秋,其实是善下围棋的某秋才对。匠石、医和、优孟也都是同理。

知道了氏,再看周武王的兄弟,比如管叔鲜,管是氏,表示封地。不过如果您要是认为这位叫姬叔鲜,嘿嘿,可就又闹笑话了。因为管叔鲜本名姬鲜,那叔什么意思呢?

这就要说说名字中的排位,先秦讲究伯仲叔季,伯(有时候也用孟)是老大(春秋称霸,也称伯,其实就是诸侯老大的意思),仲是老二,季是老幺,叔则指其余的部分。管叔鲜要翻译成现在话,就是被封在管地的叫鲜的幼子,复杂吧。

那有人就说了,老大,老二,中间的都好说,问题是怎么知道谁是老幺呢?万一定了老幺,突然又生一个怎么办?

原来古代小孩出生先有小名,行冠礼时才有名,一般孩子成年的时候兄弟排位早尘埃落定了,所以不容易出现问题。但到近代小孩出生就起名于是出了问题,据说在浙江有位老先生按伯仲叔季来给孩子起名,生到第十个觉得够了就把季字给用了,没想到第十一个孩子又出生了,没办法,只好用了个士字,所谓士,即十一:)

知道了氏和兄弟排名,再看周武王的兄弟,大多数得名字就清楚了。

但古籍难读总有意外,比如伯邑考就是个大难题。要说这位伯邑考也是大大的有名,他拒绝妲己调戏,被剁成肉酱做饼成给文王吃。文王知道以后就每天催吐,现在羑里城(关文王的地方,号称史上第一个监狱)还有一景叫吐儿冢,当然这是题外话。

再说名字,伯邑考,伯,不用说是老大的意思,按说这位应该就叫姬邑考,但有人说考是祭奠时的尊称,应该是人死了送家庙被供起来才称的,那么伯邑考应该叫姬邑。

可有人说了,邑很可能是一个封地,因为当时很少有名叫邑的,不符合命名习惯,所以应该叫姬考。我不太同意这种说法,如果是封地应该是氏,即应该放在排位的前面,该称邑伯考才对。

其他如姬伯邑,甚至名字未知的说法都有,各方争执不下,于是我们只好称呼伯邑考,至于本名只有天知道啊- -

上面说的都是男子的名字,那么先秦女子怎么命名呢?读过《东周列国志》的朋友可能马上会被这姜那姜给搞晕,感觉好像当时的女人都跟洋人一样,是先名后姓的。其实先秦女人地位低,没名,只是称姓。贵族的女子一般在姓前面要冠丈夫的封地,自己的谥号等,比如齐国的文姜,姜子牙被封齐国,所以姜是齐国的国姓。而文则是因为文姜据称很有文采,谥号文。

再有就是姓前冠用排行,比如哭倒长城的孟姜女,孟是家中老大,姜是姓,女则是代称,同母、姬、媪、妪等,没有实际的含义。孟姜女翻译成现代汉语就是姜家大女儿的意思。

Posted in 七嘴八舌 | Tagged , , | 1 Comment