2008年1月29日

zz 面试前,你必须审视自己的64个问题

Link: http://www.yeeyan.com/articles/view/allentoday/4308

Q1.描述下你自己;
Q2.你最大的优势在哪里?
Q3.你觉得自己哪里最薄弱?
Q4.谈谈你过去做过的或者没有成功的,现在依然让你觉得有损颜面的事情?
Q5.你为何(已经)离开目前的工作职位?
Q6.HR沉默一袋,你该如何应对?
Q7.我为什么要雇佣你?
Q8.对这个职位而言,你是不是显得资历过高了?
Q9.你如何看待今后五年的发展?
Q10.描述下你最理想的公司,地点,职位;
Q11.你为何想在我们公司就职?
Q12.你目前的职位选择是什么?
Q13.为何待业如此之久(职业空歇期)?
Q14.认真谈谈你目前老板(公司,经理团队等等)的强势点和弱势点;
Q15.最近读过什么好书?
Q16.谈谈一次你工作受指责批评的经历?
Q17.工作外,你有哪些兴趣爱好?
Q18.你自己觉得有什么“致命”的缺点?
Q19.向一个比自己年轻的人(少数派,妇女等等)汇报事情,你觉得怎样?
Q20.谈论一些生活私密问题;
Q21.你对公司撒过谎吗?
Q22.回顾过去,你生活中哪些需要做不同改进的?
Q23.你最近一份工作是不是可以做得更出色?
Q24.能承受工作压力?
Q25.什么使你易怒?
Q26.目前这个职业状态下为什么不多赚点钱?
Q27.生活中谁对你的影响最大,为什么?
Q28.过去你经历的最难抉择的事情是什么?
Q29.谈谈你曾经做的最厌烦的工作?
Q30.之前的工作中有没经历过连续旷工多天的情况?
Q31.如果你等够入职,你会做什么改变?
Q32.我注意到了,你并具备我们工作需要的相关经验?
Q33.如果连夜,连周加班,你如何看待?
Q34.你愿意工作地点调职或者出差?
Q35.能果断炒别人鱿鱼吗是否有过开除很多人的经历?
Q36.为何有如此多的工作经历?
Q37.如何充当一个称职的工作角色;担任一项工作任务;称职的经理;服务团体的行政人员;让公司成为行业领头羊;等等;
Q38.当你很不认同上司的疯狂想法时,你会怎么说服他?
Q39.你准备如何规划提升自己的职业历程?
Q40.如果你的团队中某个执行者不够尽职而且影响到了整个部门,你会如何处理?
Q41.你就职目前的公司已经很长时间,突然转到新的公司会不会不适应?
Q42.我可以和你当前的雇主了解下你的情况吗?
Q43.举个例子说明你的创造力(分析能力...管理能力等等)
Q44.你会在哪些方面提升自己?
Q45.你担心什么问题?
Q46.你通常一周工作多少个小时?
Q47.当一个尽职的工作(应聘职位)哪个方面最困难?
Q48.一些假定的突然事件问题;
Q49.过去面对的最具挑战性的事情?
Q50.有没考虑过自己创业?
Q51.有什么目标?
Q52.当你准备雇佣别人,你会怎么做?
Q53.如何推销这个订书机...(这个铅笔...这个钟...或者其它面试者桌面上的物品);
Q54.薪水问题-你需要多少薪水?
Q55.一些违法事件的处理;
Q56.一些“秘密的违法事件”问题;
Q57.上一份工作中有什么最困难的部分?
Q58.如何看待成功...你如何使自己到达那样的目标?
Q59.“评判主张性问题”-如何看待...堕胎...总统...死刑...(或者其它俱有争议性的问题);
Q60.如果你赢得100万的彩票,还会继续工作吗?
Q61.回顾下上一份工作,你尽了最大努力了吗?
Q62.为什么我要从公司外面雇佣你进来,我可以在公司内部考虑提升某人的?
Q63.谈谈你听说过的关于我们公司的负面消息?
Q64.从1到10份,给我这个面试官打个分;

2008年1月28日

[转]IT项目管理实务

1. 你们的项目组使用源代码管理工具了么?
应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS。
2. 你们的项目组使用缺陷管理系统了么?
应该用。ClearQuest太复杂,我的推荐是BugZilla。
3. 你们的测试组还在用Word写测试用例么?
不要用Word写测试用例(Test Case)。应该用一个专门的系统,可以是Test Manager,也可以是自己开发一个ASP.NET的小网站。主要目的是Track和Browse。
4. 你们的项目组有没有建立一个门户网站?
要有一个门户网站,用来放Contact Info、Baselined Schedule、News等等。推荐Sharepoint Portal Server 2003来实现,15分钟就搞定。买不起SPS 2003可以用WSS (Windows Sharepoint Service)。
5. 你们的项目组用了你能买到最好的工具么?
应该用尽量好的工具来工作。比如,应该用VS.NET而不是Notepad来写C#。用Notepad写程序多半只是一种炫耀。但也要考虑到经费,所以说是“你能买到最好的”。
6. 你们的程序员工作在安静的环境里么?
需要安静环境。这点极端重要,而且要保证每个人的空间大于一定面积。
7. 你们的员工每个人都有一部电话么?
需要每人一部电话。而且电话最好是带留言功能的。当然,上这么一套带留言电话系统开销不小。不过至少每人一部电话要有,千万别搞得经常有人站起来喊:“某某某电话”。《人件》里面就强烈谴责这种做法。
8. 你们每个人都知道出了问题应该找谁么?
应该知道。任何一个Feature至少都应该有一个Owner,当然,Owner可以继续Dispatch给其他人。
9. 你遇到过有人说“我以为…”么?
要消灭“我以为”。Never assume anything。
10. 你们的项目组中所有的人都坐在一起么?
需要。我反对Virtual Team,也反对Dev在美国、Test在中国这种开发方式。能坐在一起就最好坐在一起,好处多得不得了。
11. 你们的进度表是否反映最新开发进展情况?
应该反映。但是,应该用Baseline的方法来管理进度表:维护一份稳定的Schedule,再维护一份最新更改。Baseline的方法也应该用于其它的Spec。Baseline是变更管理里面的一个重要手段。
12. 你们的工作量是先由每个人自己估算的么?
应该让每个人自己估算。要从下而上估算工作量,而不是从上往下分派。除非有其他原因,比如政治任务工期固定等。
13. 你们的开发人员从项目一开始就加班么?
不要这样。不要一开始就搞疲劳战。从项目一开始就加班,只能说明项目进度不合理。当然,一些对日软件外包必须天天加班,那属于剥削的范畴。
14. 你们的项目计划中Buffer Time是加在每个小任务后面的么?
不要。Buffer Time加在每个小任务后面,很容易轻易的就被消耗掉。Buffer Time要整段的加在一个Milestone或者checkpoint前面。
15. 值得再多花一些时间,从95%做到100%好
值得,非常值得。尤其当项目后期人困马乏的时候,要坚持。这会给产品带来质的区别。
16. 登记新缺陷时,是否写清了重现步骤?
要。这属于Dev和Test之间的沟通手段。面对面沟通需要,详细填写Repro Steps也需要。
17. 写新代码前会把已知缺陷解决么?
要。每个人的缺陷不能超过10个或15个,否则必须先解决老的bug才能继续写新代码。
18. 你们对缺陷的轻重缓急有事先的约定么?
必须有定义。Severity要分1、2、3,约定好:蓝屏和Data Lost算Sev 1,Function Error算Sev 2,界面上的算Sev 3。但这种约定可以根据产品质量现状适当进行调整。
19. 你们对意见不一的缺陷有三国会议么?
必须要有。要有一个明确的决策过程。这类似于CCB (Change Control Board)的概念。
20. 所有的缺陷都是由登记的人最后关闭的么?
Bug应该由Opener关闭。Dev不能私自关闭Bug。
21. 你们的程序员厌恶修改老的代码么?
厌恶是正常的。解决方法是组织Code Review,单独留出时间来。XP也是一个方法。
22. 你们项目组有Team Morale Activity么?
每个月都要搞一次,吃饭、唱歌、Outing、打球、开卡丁车等等,一定要有。不要剩这些钱。
23. 你们项目组有自己的Logo么?
要有自己的Logo。至少应该有自己的Codename。
24. 你们的员工有印有公司Logo的T-Shirt么?
要有。能增强归属感。当然,T-Shirt要做的好看一些,最好用80支的棉来做。别没穿几次就破破烂烂的。
25. 总经理至少每月参加次项目组会议
要的。要让team member觉得高层关注这个项目。
26. 你们是给每个Dev开一个分支么?
反对。Branch的管理以及Merge的工作量太大,而且容易出错。
27. 有人长期不Check-In代码么?
不可以。对大部分项目来说,最多两三天就应该Check-In。
28. 在Check-In代码时都填写注释了么?
要写的,至少一两句话,比如“解决了Bug No.225”。如果往高处拔,这也算做“配置审计”的一部分。
29. 有没有设定每天Check-In的最后期限?
要的,要明确Check-In Deadline。否则会Build Break。
30. 你们能把所有源码一下子编译成安装文件吗?
要的。这是每日编译(Daily Build)的基础。而且必须要能够做成自动的。
31. 你们的项目组做每日编译么?
当然要做。有三样东西是软件项目/产品开发必备的:1. bug management; 2. source control; 3. daily build。
32. 你们公司有没有积累一个项目风险列表?
要。Risk Inventory。否则,下个项目开始的时候,又只能拍脑袋分析Risk了。
33. 设计越简单越好
越简单越好。设计时候多一句话,将来可能就带来无穷无尽的烦恼。应该从一开始就勇敢的砍。这叫scope management。
34. 尽量利用现有的产品、技术、代码
千万别什么东西都自己Coding。BizTalk和Sharepoint就是最好的例子,有这两个作为基础,可以把起点提高很多。或者可以尽量多用现成的Control之类的。或者尽量用XML,而不是自己去Parse一个文本文件;尽量用RegExp,而不是自己从头操作字符串,等等等等。这就是“软件复用”的体现。
35. 你们会隔一段时间就停下来夯实代码么?
要。最好一个月左右一次。传言去年年初Windows组在Stevb的命令下停过一个月增强安全。Btw,“夯”这个字念“hang”,第一声。
36. 你们的项目组每个人都写Daily Report么?
要写。五分钟就够了,写10句话左右,告诉自己小组的人今天我干了什么。一则为了沟通,二则鞭策自己(要是游手好闲一天,自己都会不好意思写的)。
37. 你们的项目经理会发出Weekly Report么?
要。也是为了沟通。内容包括目前进度,可能的风险,质量状况,各种工作的进展等。
38. 你们项目组是否至少每周全体开会一次?
要。一定要开会。程序员讨厌开会,但每个礼拜开会时间加起来至少应该有4小时。包括team meeting, spec review meeting, bug triage meeting。千万别大家闷头写code。
39. 你们项目组的会议、讨论都有记录么?
会前发meeting request和agenda,会中有人负责主持和记录,会后有人负责发meeting minutes,这都是effective meeting的要点。而且,每个会议都要形成agreements和action items。
40. 其他部门知道你们项目组在干什么么?
要发一些Newsflash给整个大组织。Show your team’s value。否则,当你坐在电梯里面,其他部门的人问:“你们在干嘛”,你回答“ABC项目”的时候,别人全然不知,那种感觉不太好。
41. 通过Email进行所有正式沟通
Email的好处是免得抵赖。但也要避免矫枉过正,最好的方法是先用电话和当面说,然后Email来确认。
42. 为项目组建立多个Mailing Group
如果在AD+Exchange里面,就建Distribution List。比如,我会建ABC Project Core Team,ABC Project Dev Team,ABC Project All Testers,ABC Project Extended Team等等。这样发起Email来方便,而且能让该收到email的人都收到、不该收到不被骚扰。
43. 每个人都知道哪里可以找到全部的文档么?
应该每个人都知道。这叫做知识管理(Knowledge Management)。最方便的就是把文档放在一个集中的File Share,更好的方法是用Sharepoint。
44. 你做决定、做变化时,告诉大家原因了么?
要告诉大家原因。Empower team member的手段之一是提供足够的information,这是MSF一开篇的几个原则之一。的确如此,tell me why是人之常情,tell me why了才能有understanding。中国人做事喜欢搞限制,限制信息,似乎能够看到某一份文件的人就是有身份的人。大错特错。权威、权力,不在于是不是能access information/data,而在于是不是掌握资源。
45. Stay agile and expect change
要这样。需求一定会变的,已经写好的代码一定会被要求修改的。做好心理准备,对change不要抗拒,而是expect change。
46. 你们有没有专职的软件测试人员?
要有专职测试。如果人手不够,可以peer test,交换了测试。千万别自己测试自己的。
47. 你们的测试有一份总的计划来规定做什么和怎么做么?
这就是Test Plan。要不要做性能测试?要不要做Usability测试?什么时候开始测试性能?测试通过的标准是什么?用什么手段,自动的还是手动的?这些问题需要用Test Plan来回答。
48. 你是先写Test Case然后再测试的么?
应该如此。应该先设计再编程、先test case再测试。当然,事情是灵活的。我有时候在做第一遍测试的同时补上test case。至于先test case再开发,我不喜欢,因为不习惯,太麻烦,至于别人推荐,那试试看也无妨。
49. 你是否会为各种输入组合创建测试用例?
不要,不要搞边界条件组合。当心组合爆炸。有很多test case工具能够自动生成各种边界条件的组合——但要想清楚,你是否有时间去运行那么多test case。
50. 你们的程序员能看到测试用例么?
要。让Dev看到Test Case吧。我们都是为了同一个目的走到一起来的:提高质量。
51. 你们是否随便抓一些人来做易用性测试?
要这么做。自己看自己写的程序界面,怎么看都是顺眼的。这叫做审美疲劳——臭的看久了也就不臭了,不方便的永久了也就习惯了。
52. 你对自动测试的期望正确么?
别期望太高。依我看,除了性能测试以外,还是暂时先忘掉“自动测试”吧,忘掉WinRunner和LoadRunner吧。对于国内的软件测试的现状来说,只能“矫枉必须过正”了。
53. 你们的性能测试是等所有功能都开发完才做的么?
不能这样。性能测试不能被归到所谓的“系统测试”阶段。早测早改正,早死早升天。
54. 你注意到测试中的杀虫剂效应了么?
虫子有抗药性,Bug也有。发现的新Bug越来越少是正常的。这时候,最好大家交换一下测试的area,或者用用看其他工具和手法,就又会发现一些新bug了。
55. 你们项目组中有人能说出产品的当前整体质量情况么?
要有。当老板问起这个产品目前质量如何,Test Lead/Manager应该负责回答。
56. 你们有单元测试么?
单元测试要有的。不过没有单元测试也不是不可以,我做过没有单元测试的项目,也做成功了——可能是侥幸,可能是大家都是熟手的关系。还是那句话,软件工程是非常实践、非常工程、非常灵活的一套方法,某些方法在某些情况下会比另一些方法好,反之亦然。
57. 你们的程序员是写完代码就扔过墙的么?
大忌。写好一块程序以后,即便不做单元测试,也应该自己先跑一跑。虽然有了专门的测试人员,做开发的人也不可以一点测试都不做。微软还有Test Release Document的说法,程序太烂的话,测试有权踢回去。
58. 你们的程序中所有的函数都有输入检查么?
不要。虽然说做输入检查是write secure code的要点,但不要做太多的输入检查,有些内部函数之间的参数传递就不必检查输入了,省点功夫。同样的道理,未必要给所有的函数都写注释。写一部分主要的就够了。
59. 产品有统一的错误处理机制和报错界面么?
要有。最好能有统一的error message,然后每个error message都带一个error number。这样,用户可以自己根据error number到user manual里面去看看错误的具体描述和可能原因,就像SQL Server的错误那样。同样,ASP.NET也要有统一的Exception处理。可以参考有关的Application Block。
60. 你们有统一的代码书写规范么?
要有。Code Convention很多,搞一份来发给大家就可以了。当然,要是有FxCop这种工具来检查代码就更好了。
61. 你们的每个人都了解项目的商业意义么?
要。这是Vision的意思。别把项目只当成工作。有时候要想着自己是在为中国某某行业的信息化作先驱者,或者时不时的告诉team member,这个项目能够为某某某国家部门每年节省多少多少百万的纳税人的钱,这样就有动力了。平凡的事情也是可以有个崇高的目标的。
62. 产品各部分的界面和操作习惯一致么?
要这样。要让用户觉得整个程序好像是一个人写出来的那样。
63. 有可以作为宣传亮点的Cool Feature么?
要。这是增强团队凝聚力、信心的。而且,“一俊遮百丑”,有亮点就可以掩盖一些问题。这样,对于客户来说,会感觉产品从质量角度来说还是acceptable的。或者说,cool feature或者说亮点可以作为质量问题的一个事后弥补措施。
64. 尽可能缩短产品的启动时间
要这样。软件启动时间(Start-Up time)是客户对性能好坏的第一印象。
65. 不要过于注重内在品质而忽视了第一眼的外在印象
程序员容易犯这个错误:太看重性能、稳定性、存储效率,但忽视了外在感受。而高层经理、客户正相反。这两方面要兼顾,协调这些是PM的工作。
66. 你们根据详细产品功能说明书做开发么?
要这样。要有设计才能开发,这是必须的。设计文档,应该说清楚这个产品会怎么运行,应该采取一些讲故事的方法。设计的时候千万别钻细节,别钻到数据库、代码等具体实现里面去,那些是后面的事情,一步步来不能着急。
67. 开始开发和测试之前每个人都仔细审阅功能设计么?
要做。Function Spec review是用来统一思想的。而且,review过以后形成了一致意见,将来再也没有人可以说“你看,当初我就是反对这么设计的,现在吃苦头了吧”
68. 所有人都始终想着The Whole Image么?
要这样。项目里面每个人虽然都只是在制造一片叶子,但每个人都应该知道自己在制造的那片叶子所在的树是怎么样子的。我反对软件蓝领,反对过分的把软件制造看成流水线、车间。参见第61条。
69. Dev工作的划分是单纯纵向或横向的么?
不能单纯的根据功能模块分,或者单纯根据表现层、中间层、数据库层分。我推荐这么做:首先根据功能模块分,然后每个“层”都有一个Owner来Review所有人的设计和代码,保证consistency。
70. 你们的程序员写程序设计说明文档么?
要。不过我听说微软的程序员1999年以前也不写。所以说,写不写也不是绝对的,偷懒有时候也是可以的。参见第56条。
71. 你在招人面试时让他写一段程序么?
要的。我最喜欢让人做字符串和链表一类的题目。这种题目有很多循环、判断、指针、递归等,既不偏向过于考算法,也不偏向过于考特定的API。
72. 你们有没有技术交流讲座?
要的。每一两个礼拜搞一次内部的Tech Talk或者Chalk Talk吧。让组员之间分享技术心得,这笔花钱送到外面去培训划算。
73. 你们的程序员都能专注于一件事情么?
要让程序员专注一件事。例如说,一个部门有两个项目和10个人,一种方法是让10个人同时参加两个项目,每个项目上每个人都花50%时间;另一种方法是5个人去项目A,5个人去项目B,每个人都100%在某一个项目上。我一定选后面一种。这个道理很多人都懂,但很多领导实践起来就把属下当成可以任意拆分的资源了。
74. 你们的程序员会夸大完成某项工作所需要的时间么?
会的,这是常见的,尤其会在项目后期夸大做某个change所需要的时间,以次来抵制change。解决的方法是坐下来慢慢磨,磨掉程序员的逆反心理,一起分析,并把估算时间的颗粒度变小。
75. 尽量不要用Virtual Heads
最好不要用Virtual Heads。Virtual heads意味着resource is not secure,shared resource会降低resource的工作效率,容易增加出错的机会,会让一心二用的人没有太多时间去review spec、review design。一个dedicated的人,要强过两个只能投入50%时间和精力的人。我是吃过亏的:7个part time的tester,发现的Bug和干的活,加起来还不如两个full-time的。参见第73条。73条是针对程序员的,75条是针对Resource Manager的。

2008年1月27日

Bayes学习体会(1)

近日明白一个道理,一定要非常认真的判断你即将做的事情是否值得做,千万不要凭着一时的冲动浪费大量的时间,以至于无法集中注意力完成主要的事情。按照80-20原则,我们只有20%的事情是非常重要的。事情一旦选定那就要全身心的投入并且完成。

数日前听朱慕华介绍Hal Daume III,说他原先初学统计和机器学习的时候非常痛苦,经历了这段痛苦之后他才进入了一个长期的发展阶段。现在想来,自己仿佛也需要经历一段这样的痛苦。当然,不能说经历这种痛苦是科研有所成果的必要条件,只能看成是一种充分条件吧。

我首先开始学习Hal收集的Bayesian Method for NLP资料中推荐的Books中的第一本“James O. Berger. Statistical Decision Theory and Bayesian Analysis. Springer, 1985.”。本想到NUS图书馆借阅这本书,不想居然被人借走了。好在经过深度挖掘,终于找到了这本书的第二版的中文版电子版。现在正在进行的就是每天学习10页,不求多,只求精和深入。预计70天才能看完这本书。

下面来说说我这几日来学习Bayesian的感受吧。

第一感受,Bayesian方法很神奇,真的!这个观点Andrew McCallum也曾经说过。

第二感受就是学习Bayesian确实需要投入大量的时间。

在前30页的学习体会到如下一些个人认为比较新颖的观点或者概念:

  1. (p1)经典统计学在进行推断的时候直接利用样本信息(数据来自统计调查),这些经典推断大都不考虑所作的推断将被应用的领域。而决策论则试图将样本信息与问题的其他相关性质结合起来考虑,从而可以做出一个最好的决策。个人猜想面向问题的自然语言处理本质上就是一种应用机器学习方法的决策论。从这个层面考虑,我正在研究的共指消解以及其他一些相关自然语言处理问题,在结合背景知识以及与问题结合的时候都是需要从决策论的角度来思考的。
  2. (p2)损失函数是描述对决策带来的可能值所造成的损失,主要是统计学家采用的术语。经济界或者商界的术语是“所得”(效用)。其实,所得就是负的损失,两者并没有实质的区别。我第一次听说损失函数是在2004年北京语言文化大学第二届学生计算语言会议后的自然语言处理学习班上李航老师介绍机器学习方法的讲座上。当时感觉这个术语比较有趣。后来才发现,这个函数的定义以及处理居然是机器学习里面非常重要的一个问题。本来重要的概念,居然在自己的研究工作中从未直接采用过。看来的确需要好好学学统计学的。
  3. (p2)对于统计决策,除了损失函数,另外一种非样本信息就是先验信息。这是关于统计参数的信息,但并非来自统计调查,一般来自类似情况包含类似的变量的过去的经验。个人认为就是训练语料上获得的信息。
  4. (p3)将先验信息正式的纳入统计学中去并探索如何利用这种信息的方法被称为贝叶斯分析(名称来自Bares(1763))。贝叶斯分析与决策论走到一起是很自然的,部分原因是它们都要利用非试验信息源的共同目标,另一部分原因是深层次的理论把它们联结起来。
  5. (p7)在很多问题中都没有明确的损失函数和明显的先验信息,这些量很含糊不清,甚至不唯一,其中最重要的例子就是统计推断问题。在统计推断中,目的并不是做一个决策,而是提供统计论证的一个“概要”,以便将来的各种“应用者”可以很容易的把这种论证用到它们自己的决策过程中去。个人认为,如果自然语言处理研究人员拥有类似的统计推断框架的话,他们的工作就能得到极大的推进,只是到目前为止我还没有看到的辅助于自然语言处理的统计推断框架。
  6. (p11)对于具体问题,常常存在一大类不能找到更优结果的损失函数,也就是说它们是交叉的,再换句话说就是它们各自在不同的地方比其它的好。这种情形使得我们的学习问题变得比较困难。不知道近年流行的SVM是不是在理论框架上解决了这个问题。
  7. (p17)条件贝叶斯原理:选择一行为equation(3)使贝叶斯期望损失equation(4) 最小(假设最小值是可以达到的)。这样的行为被称为贝叶斯行为,记为equation(5) 。个人感觉这是一个直观的概念,但是平时在我的研究工作中还真的很难做出这样的提炼。数学的抽象能力在统计决策理论中表现得还是淋漓尽致的。
  8. (p21)不变性原理基本上是说:如果两个问题具有同样的形式结构(即具有相同的样本空间、参数空间、密度和损失函数),则在每个问题中都应该采取同样的决策。当只有一个具体问题时,此原理用于考虑问题的变换(度量单位尺度的改变),变换后,问题仍有相同的结构。原来问题与变换后问题的决策法则限定为相同,这就产生所谓的“不变的”决策法则。
  9. (p30)似然原理:有了观测值equation(6)后,在做关于equation(7) 的推断或决策时,所有与试验有关的信息均被包含在equation(6)的似然函数之中,而且,如果两个似然函数(作为equation(7)的函数)是成正比例的,则它们关于equation(7)含有相同的信息。称为“似然函数”的直观原因是,使equation(8)大的equation(7)比使equation(8)小的equation(7)更“像是”equation(7)的真值。因为,如果equation(8)大,equation(6)的出现就更有道理。(这里对“似然”的意思就是“像真的”。自此,我终于弄懂了什么叫似然函数^-^)。

这种学习体会还真是不好写,不过写完再重读一下,感觉自己对这30页的内容理解得深入了一些。以后采用的方式就是每个周末写一个本周的Bayesian学习体会吧。争取弄个学习系列 :)

2008年1月26日

[好文转载]我的Youtube使用及精彩频道推荐

From: http://www.quhuashuai.com/2008/01/how-to-use-youtube/

大家都会经常浏览视频分享网站,国内的土豆,优酷,六间房什么的,因为网络的原因,Hugh平时都不去访问,所以Youtube就成了Hugh比较多的选择。这次就说说自己平时都用Youtube干些什么,同时推荐几个不错的频道。

  1. UC Berkeley的课程视频:当加州伯克利分校推出课程视频的时候,Hugh曾经在博客上介绍过,大家可以再去了解下那篇文章《UC Berkeley的YouTube频道提供完整课程视频!》,大家可以从这里找到完整的播放列表。
  2. MIT开放课程视频:很多朋友可能会选择去MIT开放课程的主页浏览,下载相关的课程内容,不过Hugh会经常去Youtube上观看课程视频,主要是Gilbert Strang的一些课程视频,实在很喜欢他讲的课,只可惜没办法亲身听一趟课了。
  3. 使用Youtube观看讲座视频。如果你曾经看过Hugh介绍Randy Pausch的文章,那么你一定明白。可以在Youtube上面观看这些视频分享,尽管一场演讲被分割成几个部分,但是依然不错。如果你不喜欢可以在google video上找到更好的版本。
  4. 使用Youtube观看Google Talk当然直接去google video里找也可以。出现在google talk里面的也是很多著名人物的演讲,最近Hugh在上面看了几个美国大选候选人的视频,都不错,比如希拉里,奥巴马等等,如果你有兴趣,可以去看看。
  5. 使用Youtube学习软件使用。如果你在学习软件的时候,希望能够看到些视频教学的话,不妨去youtube搜索一下,比如photoshop的使用,可能有中文内容,给出几个链接:1,2,3,或者你可以看看比如c++,vim等内容的介绍。
  6. 使用Youtube来学习英语。本身Youtube上面就是很多的英文内容,大家多注意听听也会有好处的。还有很多专门为英语学习准备的内容,比如KanTalk这个在线语言学习社区推出的FunTalk对话课程,每一课都在Youtube上面有视频,内容也挺多的,旅游,政治,商业,休闲,社会等等。
  7. 观看NBA精彩视频。其实要是在国内就不必这样了,欧洲这边只能在半夜2,3点看直播,所以一般就去youtube上面找找Highlight看看,呵呵。有的时候直接搜Houston Rockets,很多时候就直接在订阅里的NBA频道里面看看。

Hugh还在Openculture这个站点看到一些youtube频道的介绍,自己还没有来得及看,推荐给大家: The Nobel Prize, , 以及BBC Worldwide,更多的频道介绍可以在这里找到,不过都是英文介绍,选择权在大家手里。

不知道大家平时怎么使用视频分享网站的,不妨分享一下你们的使用经历。如果你对开放性课程感兴趣的话,还可以看看Hugh曾经写过的这几篇文章:,《耶鲁大学推出开放性课程材料》,《25个免费的在线教育资源》,也可以到开放式课程计划找到很多的内容。

2008年1月24日

跟进Bayes

提起Bayes,俺真的有点头疼,因为无数次的聆听采用Bayes方法的NLP时几乎都会存在疑问:为什么要这么弄呢,有更好的方法么?以至于一听Bayes方面的东东俺就会打瞌睡 :)

在朱慕华的推荐下,俺开始非常认真的学习起Hal Daume III的nlper blog起来。以前就知道这个blog非常不错,朱慕华说Hal在读博期间也曾认为NLP做不动了,然后开始痛下决心,经历万难,学好了概率,然后才成为现在的牛人的。这段经历,不自己看这个blog的人,我想是不会清楚的。感谢朱慕华的推荐。

我打算将这个blog的文章按照时间顺序通读一遍。第一篇是welcome, 第二篇是interesting topics。感觉Hal的眼光还是很独到的,提出了一些非常新颖的问题来。或许大师都是这样的 :)

第三篇就是介绍Hal主持的NIPS的讨论会BayesNLP了。看完之后,不禁让我想起了“木桶定律”(水桶定律:一只水桶能装多少水, 完全取决于它最短的那块木板)。其中还提到了我最为敬仰的一位研究人员Andrew McCallum。原来他们都是认识的啊。

想要仔细了解一下Bayesian方法在NLP上真正的用途,后来看到了HLT-NAACL2006上有Hal做的Tutorial Beyond EM: Bayesian Techniques for Human Language Technology Researchers。苦于找不到这个报告的下载,只能给Hal发信索取了。

两天前的邮件,想不到今天一早收到了Hal的回信。原来,他已经收集整理了一堆Bayes for NLP的资料,当然也包括他在HLT-NAACL2006上的Tutorial。奇怪自己问什么就没有搜索到呢?

呵呵,差点忘了,分享一下Hal告诉我的Bayes for NLP的网页地址:Bayesian Methods for NLP.

让交流成为习惯!

2008年1月22日

zz 时间管理之任务猎杀日

迅速提升三倍你的工作效率

工作让你慢慢透不过气来吗?待办事项,计划和突发的琐事不停地积累已经把你包围?遇到这种情况时,你的最佳策略就是先走一步,超前工作。完成今天所有的任务甚至更多,你才能有呼吸的空间。

你会怎么做呢?当我面对这个问题,我的答案是,来一次“任务猎杀日" —— 这一天会是我效率最高的一天。我将预留大量的时间来完成待办事项上的任务并且超前工作。我发现,如果你计划得当,你可以让明天的效率比平常高出三倍!

    * 怎样设定“任务猎杀日”呢?

我已经成功完成了数以百计的“任务猎杀日”。因此,如果你正准备开始你自己的“任务猎杀日",可以参考如下步骤:

早起:如果你不是一个通常很早起床的人,请调早你的闹钟。在5:00-6:00起床有两个作用。首先,它给你一段在上课,工作,或家人醒来前的安静时间。其次,它能建立一种成就感,这可以激励你度过一整天。

早操:这并非绝对必要,但我发现用跑步或在房间里做几个俯卧撑来开始新的一天是另一种非常好的激励方法。而且,三十分钟的晨练可以赶走你身体里昏昏沉沉的感觉。

固定的任务清单:在你开始这一天以前,写下所有你必须完成的任务。一旦你完成这项清单,也就完成了一天的工作,然后你可以去做点真正想做的事情。有一个固定的工作目标可以让你更好的集中精力,“今天要工作一整天”,类似这种想法反而会导致拖延。

隔立自己:我的大部分工作是靠个人完成。这意味着,在“任务猎杀日”里,我的社交活动几乎为零。为了可以集中精力而不分心,就做一天的隐士吧。锁上房间或办公室的大门,直到你解决掉清单上的所有任务。

断“线”:电视、网络、Facebook、电话和即时通讯在这一天里都要保持离线。如果你实在需要互联网(比如:回电子邮件是工作清单的一部分)那么就专注于你的任务,别去做其他的。如果你沉溺于到处在网络闲逛,那就断线吧。

重要的工作优先:关于如何组织你的工作这个问题,那就是大石头优先!也就是把要完成的最重要的任务放在一天的开始,而不是结束。这样,你就能把你的焦点放在当前最重要的任务上。当然这一条也有例外,但你得把它作为一项总原则来遵循。

没有中途休息:在这一天中,任何形式的休息都应该尽量减少。但尤其是任务当中的休息。只有当你完成清单上相当一部分的工作后,你才能站起来去喘口气。如果你的论文只写到一半,先结束它,然后再去吃午饭。

休息最少化:一天没有悠闲的咖啡时光不会杀了你。我的原则是,大的任务之间有5分钟休息或花费20-30分钟来解决三餐都是可行的。但别到处闲晃,即使只有1小时。除非你已解决掉所有的项目,否则这会让你的一天以失败告终。

集中琐事:集中你全部的琐事(扔垃圾,修门铰链,装订等) ,然后一次解决。这可以帮助提高效率,因为它能减少工作流程的中断次数。

加快走路步伐:在这一天里,对于你做的每件事,你都得专注并且有紧迫感。如果在任务间要拿点什么东西,加快走路步伐能提醒你还有一个重要的使命要完成:清空你的任务清单。如果你需要通勤或开车,在这段时间里可以放盘磁带来提醒自己——你没有时间能随意浪费。

加速:一次承担所有任务并加速完成它们。我常常一次写几千字,甚至曾经一连写过30页的电子书。通常,人们很难拒绝休息的诱惑,但一旦你进入状态,请竭尽所能来维持它。

做重要的事,不仅是紧急的事:这条前面已说过,但它需要被再次提到。任务猎杀日是用来解决那些重要的长期的工作的,也就是说不要把时间仅仅放在当前问题的解决上。我建议在一天行程当中安排一个不亟须完成的长期计划。参考阅读《为什么要区分紧急与重要任务》

放一天假:在成功的处理完所有待办事项的一天后,给自己放天假。这可以帮助你在经历了一整天疲劳的工作后恢复精力。即使你第二天什么都不做,前几天的超前工作通常可以弥补。花一些时间与你的家人相处,读一本书,或是睡到中午。经过了三倍效率的一天,你值得拥有这些!

    * 弥缝啰嗦

“任务猎杀日”感觉就像是考试抱佛脚一样,临时进入紧急状态,开始忙碌。虽然这样集中起来完成任务效果不错,但这不能说明你应该经常进行任务猎杀日。如果你要启动任务猎杀日了,那说明前一段时间你都没有好好利用时间。所以除了要赶快完成堆积的任务外,你还应该反省一下为什么会有这么多任务聚集起来未完成!

2008年1月21日

zz Java语言编码规范

名称    Java语言编码规范(Java Code Conventions)
译者    晨光(Morning)
简介    本文档讲述了Java语言的编码规范,较之陈世忠先生《c++编码规范》的浩繁详尽,此文当属短小精悍了。而其中所列之各项条款,从编码风格,到注意事项,不单只Java,对于其他语言,也都很有借鉴意义。因为简短,所以易记,大家不妨将此作为handbook,常备案头,逐一对验。
声明    如需复制、传播,请附上本声明,谢谢。
原文出处:http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html,
译文出处:http://morningspace.51.net/,moyingzz@etang.com

目录
1 介绍

    * 1.1 为什么要有编码规范
    * 1.2 版权声明

2 文件名

    * 2.1 文件后缀
    * 2.2 常用文件名

3 文件组织

    * 3.1 Java源文件
          o 3.1.1 开头注释
          o 3.1.2 包和引入语句
          o 3.1.3 类和接口声明

4 缩进排版

    * 4.1 行长度
    * 4.2 换行

5 注释

    * 5.1 实现注释的格式
          o 5.1.1 块注释
          o 5.1.2 单行注释
          o 5.1.3 尾端注释
          o 5.1.4 行末注释
    * 5.2 文挡注释

6 声明

    * 6.1 每行声明变量的数量
    * 6.2 初始化
    * 6.3 布局
    * 6.4 类和接口的声明

7 语句

    * 7.1 简单语句
    * 7.2 复合语句
    * 7.3 返回语句
    * 7.4 if,if-else,if else-if else语句
    * 7.5 for语句
    * 7.6 while语句
    * 7.7 do-while语句
    * 7.8 switch语句
    * 7.9 try-catch语句

8 空白

    * 8.1 空行
    * 8.2 空格

9 命名规范

10 编程惯例

    * 10.1 提供对实例以及类变量的访问控制
    * 10.2 引用类变量和类方法
    * 10.3 常量
    * 10.4 变量赋值
    * 10.5 其它惯例
          o 10.5.1 圆括号
          o 10.5.2 返回值
          o 10.5.3 条件运算符"?"前的表达式"?"前的表达式
          o 10.5.4 特殊注释

11 代码范例

    * 11.1 Java源文件范例

1 介绍(Introduction)

1.1 为什么要有编码规范(Why Have Code Conventions)

编码规范对于程序员而言尤为重要,有以下几个原因:

- 一个软件的生命周期中,80%的花费在于维护
- 几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护
- 编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码
- 如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品

为了执行规范,每个软件开发人员必须一致遵守编码规范。每个人。

1.2 版权声明(Acknowledgments)

本文档反映的是Sun MicroSystems公司,Java语言规范中的编码标准部分。主要贡献者包括:Peter King,Patrick Naughton,Mike DeMoney,Jonni Kanerva,Kathy Walrath以及Scott Hommel。

本文档现由Scott Hommel维护,有关评论意见请发至shommel@eng.sun.com

2 文件名(File Names)

这部分列出了常用的文件名及其后缀。

2.1 文件后缀(File Suffixes)

Java程序使用下列文件后缀:

文件类别    文件后缀
Java源文件    .java
Java字节码文件    .class

2.2 常用文件名(Common File Names)

常用的文件名包括:

文件名    用途
GNUmakefile    makefiles的首选文件名。我们采用gnumake来创建(build)软件。
README    概述特定目录下所含内容的文件的首选文件名

3 文件组织(File Organization)

一个文件由被空行分割而成的段落以及标识每个段落的可选注释共同组成。超过2000行的程序难以阅读,应该尽量避免。"Java源文件范例"提供了一个布局合理的Java程序范例。

3.1 Java源文件(Java Source Files)

每个Java源文件都包含一个单一的公共类或接口。若私有类和接口与一个公共类相关联,可以将它们和公共类放入同一个源文件。公共类必须是这个文件中的第一个类或接口。

Java源文件还遵循以下规则:

- 开头注释(参见"开头注释")
- 包和引入语句(参见"包和引入语句")
- 类和接口声明(参见"类和接口声明")

3.1.1 开头注释(Beginning Comments)

所有的源文件都应该在开头有一个C语言风格的注释,其中列出类名、版本信息、日期和版权声明:

  /*
   * Classname
   *
   * Version information
   *
   * Date
   *
   * Copyright notice
   */

3.1.2 包和引入语句(Package and Import Statements)

在多数Java源文件中,第一个非注释行是包语句。在它之后可以跟引入语句。例如:

  package java.awt;

  import java.awt.peer.CanvasPeer;

3.1.3 类和接口声明(Class and Interface Declarations)

下表描述了类和接口声明的各个部分以及它们出现的先后次序。参见"Java源文件范例"中一个包含注释的例子。

     类/接口声明的各部分    注解
1    类/接口文档注释(/**……*/)    该注释中所需包含的信息,参见"文档注释"
2    类或接口的声明    
3    类/接口实现的注释(/*……*/)如果有必要的话    该注释应包含任何有关整个类或接口的信息,而这些信息又不适合作为类/接口文档注释。
4    类的(静态)变量    首先是类的公共变量,随后是保护变量,再后是包一级别的变量(没有访问修饰符,access modifier),最后是私有变量。
5    实例变量    首先是公共级别的,随后是保护级别的,再后是包一级别的(没有访问修饰符),最后是私有级别的。
6    构造器    
7    方法    这些方法应该按功能,而非作用域或访问权限,分组。例如,一个私有的类方法可以置于两个公有的实例方法之间。其目的是为了更便于阅读和理解代码。

4 缩进排版(Indentation)

4个空格常被作为缩进排版的一个单位。缩进的确切解释并未详细指定(空格 vs. 制表符)。一个制表符等于8个空格(而非4个)。

4.1 行长度(Line Length)

尽量避免一行的长度超过80个字符,因为很多终端和工具不能很好处理之。

注意:用于文档中的例子应该使用更短的行长,长度一般不超过70个字符。

4.2 换行(Wrapping Lines)

当一个表达式无法容纳在一行内时,可以依据如下一般规则断开之:

- 在一个逗号后面断开
- 在一个操作符前面断开
- 宁可选择较高级别(higher-level)的断开,而非较低级别(lower-level)的断开
- 新的一行应该与上一行同一级别表达式的开头处对齐
- 如果以上规则导致你的代码混乱或者使你的代码都堆挤在右边,那就代之以缩进8个空格。

以下是断开方法调用的一些例子:

  someMethod(longExpression1, longExpression2, longExpression3,
                   longExpression4, longExpression5);

  var = someMethod1(longExpression1,
                            someMethod2(longExpression2,
                                               longExpression3));

以下是两个断开算术表达式的例子。前者更好,因为断开处位于括号表达式的外边,这是个较高级别的断开。

  longName1 = longName2 * (longName3 + longName4 - longName5)
                     + 4 * longname6; //PREFFER

  longName1 = longName2 * (longName3 + longName4
                                         - longName5) + 4 * longname6; //AVOID

以下是两个缩进方法声明的例子。前者是常规情形。后者若使用常规的缩进方式将会使第二行和第三行移得很靠右,所以代之以缩进8个空格

  //CONVENTIONAL INDENTATION
  someMethod(int anArg, Object anotherArg, String yetAnotherArg,
                    Object andStillAnother) {
    ...
  }

  //INDENT 8 SPACES TO AVOID VERY DEEP INDENTS
  private static synchronized horkingLongMethodName(int anArg,
          Object anotherArg, String yetAnotherArg,
          Object andStillAnother) {
    ...
  }

if语句的换行通常使用8个空格的规则,因为常规缩进(4个空格)会使语句体看起来比较费劲。比如:

  //DON’T USE THIS INDENTATION
  if ((condition1 && condition2)
      || (condition3 && condition4)
      ||!(condition5 && condition6)) { //BAD WRAPS
      doSomethingAboutIt();             //MAKE THIS LINE EASY TO MISS
  }

  //USE THIS INDENTATION INSTEAD
  if ((condition1 && condition2)
          || (condition3 && condition4)
          ||!(condition5 && condition6)) {
      doSomethingAboutIt();
  }

  //OR USE THIS
  if ((condition1 && condition2) || (condition3 && condition4)
          ||!(condition5 && condition6)) {
      doSomethingAboutIt();
  }

这里有三种可行的方法用于处理三元运算表达式:

  alpha = (aLongBooleanExpression) ? beta : gamma;

  alpha = (aLongBooleanExpression) ? beta
                                   : gamma;

  alpha = (aLongBooleanExpression)
          ? beta
          : gamma;

5 注释(Comments)

Java程序有两类注释:实现注释(implementation comments)和文档注释(document comments)。实现注释是那些在C++中见过的,使用/*...*/和//界定的注释。文档注释(被称为"doc comments")是Java独有的,并由/**...*/界定。文档注释可以通过javadoc工具转换成HTML文件。

实现注释用以注释代码或者实现细节。文档注释从实现自由(implementation-free)的角度描述代码的规范。它可以被那些手头没有源码的开发人员读懂。

注释应被用来给出代码的总括,并提供代码自身没有提供的附加信息。注释应该仅包含与阅读和理解程序有关的信息。例如,相应的包如何被建立或位于哪个目录下之类的信息不应包括在注释中。

在注释里,对设计决策中重要的或者不是显而易见的地方进行说明是可以的,但应避免提供代码中己清晰表达出来的重复信息。多余的的注释很容易过时。通常应避免那些代码更新就可能过时的注释。

注意:频繁的注释有时反映出代码的低质量。当你觉得被迫要加注释的时候,考虑一下重写代码使其更清晰。

注释不应写在用星号或其他字符画出来的大框里。注释不应包括诸如制表符和回退符之类的特殊字符。

5.1 实现注释的格式(Implementation Comment Formats)

程序可以有4种实现注释的风格:块(block)、单行(single-line)、尾端(trailing)和行末(end-of-line)。

5.1.1 块注释(Block Comments)

块注释通常用于提供对文件,方法,数据结构和算法的描述。块注释被置于每个文件的开始处以及每个方法之前。它们也可以被用于其他地方,比如方法内部。在功能和方法内部的块注释应该和它们所描述的代码具有一样的缩进格式。

块注释之首应该有一个空行,用于把块注释和代码分割开来,比如:

  /*
   * Here is a block comment.
   */

块注释可以以/*-开头,这样indent(1)就可以将之识别为一个代码块的开始,而不会重排它。

  /*-
    * Here is a block comment with some very special
    * formatting that I want indent(1) to ignore.
    *
    *    one
    *        two
    *            three
    */

注意:如果你不使用indent(1),就不必在代码中使用/*-,或为他人可能对你的代码运行indent(1)作让步。

参见"文档注释"

5.1.2 单行注释(Single-Line Comments)

短注释可以显示在一行内,并与其后的代码具有一样的缩进层级。如果一个注释不能在一行内写完,就该采用块注释(参见"块注释")。单行注释之前应该有一个空行。以下是一个Java代码中单行注释的例子:

  if (condition) {

    /* Handle the condition. */
    ...
  }

5.1.3 尾端注释(Trailing Comments)

极短的注释可以与它们所要描述的代码位于同一行,但是应该有足够的空白来分开代码和注释。若有多个短注释出现于大段代码中,它们应该具有相同的缩进。

以下是一个Java代码中尾端注释的例子:

  if (a == 2) {
      return TRUE;              /* special case */
  } else {
      return isPrime(a);         /* works only for odd a */
  }

5.1.4 行末注释(End-Of-Line Comments)

注释界定符"//",可以注释掉整行或者一行中的一部分。它一般不用于连续多行的注释文本;然而,它可以用来注释掉连续多行的代码段。以下是所有三种风格的例子:

  if (foo > 1) {

      // Do a double-flip.
      ...
  }
  else {
      return false;          // Explain why here.
  }

  //if (bar > 1) {
  //
  //    // Do a triple-flip.
  //    ...
  //}
  //else {
  //    return false;
  //}

5.2 文档注释(Documentation Comments)

注意:此处描述的注释格式之范例,参见"Java源文件范例"

若想了解更多,参见"How to Write Doc Comments for Javadoc",其中包含了有关文档注释标记的信息(@return, @param, @see):

http://java.sun.com/javadoc/writingdoccomments/index.html

若想了解更多有关文档注释和javadoc的详细资料,参见javadoc的主页:

http://java.sun.com/javadoc/index.html

文档注释描述Java的类、接口、构造器,方法,以及字段(field)。每个文档注释都会被置于注释定界符/**...*/之中,一个注释对应一个类、接口或成员。该注释应位于声明之前:

  /**
    * The Example class provides ...
    */
  public class Example { ...

注意顶层(top-level)的类和接口是不缩进的,而其成员是缩进的。描述类和接口的文档注释的第一行(/**)不需缩进;随后的文档注释每行都缩进1格(使星号纵向对齐)。成员,包括构造函数在内,其文档注释的第一行缩进4格,随后每行都缩进5格。

若你想给出有关类、接口、变量或方法的信息,而这些信息又不适合写在文档中,则可使用实现块注释(见5.1.1)或紧跟在声明后面的单行注释(见5.1.2)。例如,有关一个类实现的细节,应放入紧跟在类声明后面的实现块注释中,而不是放在文档注释中。

文档注释不能放在一个方法或构造器的定义块中,因为Java会将位于文档注释之后的第一个声明与其相关联。

6 声明(Declarations)

6.1 每行声明变量的数量(Number Per Line)

推荐一行一个声明,因为这样以利于写注释。亦即,

  int level;  // indentation level
  int size;   // size of table

要优于,

int level, size;

不要将不同类型变量的声明放在同一行,例如:

  int foo,  fooarray[];   //WRONG!

注意:上面的例子中,在类型和标识符之间放了一个空格,另一种被允许的替代方式是使用制表符:

  int        level;         // indentation level
  int        size;          // size of table
  Object    currentEntry;  // currently selected table entry

6.2 初始化(Initialization)

尽量在声明局部变量的同时初始化。唯一不这么做的理由是变量的初始值依赖于某些先前发生的计算。

6.3 布局(Placement)

只在代码块的开始处声明变量。(一个块是指任何被包含在大括号"{"和"}"中间的代码。)不要在首次用到该变量时才声明之。这会把注意力不集中的程序员搞糊涂,同时会妨碍代码在该作用域内的可移植性。

  void myMethod() {
      int int1 = 0;         // beginning of method block

      if (condition) {
          int int2 = 0;     // beginning of "if" block
          ...
      }
  }

该规则的一个例外是for循环的索引变量

  for (int i = 0; i < maxLoops; i++) { ... }

避免声明的局部变量覆盖上一级声明的变量。例如,不要在内部代码块中声明相同的变量名:

  int count;
  ...
  myMethod() {
      if (condition) {
          int count = 0;     // AVOID!
          ...
      }
      ...
  }

6.4 类和接口的声明(Class and Interface Declarations)

当编写类和接口是,应该遵守以下格式规则:

- 在方法名与其参数列表之前的左括号"("间不要有空格
- 左大括号"{"位于声明语句同行的末尾
- 右大括号"}"另起一行,与相应的声明语句对齐,除非是一个空语句,"}"应紧跟在"{"之后

  class Sample extends Object {
      int ivar1;
      int ivar2;

      Sample(int i, int j) {
          ivar1 = i;
          ivar2 = j;
      }

      int emptyMethod() {}

      ...
  }

- 方法与方法之间以空行分隔

7 语句(Statements)

7.1 简单语句(Simple Statements)

每行至多包含一条语句,例如:

  argv++;       // Correct
  argc--;       // Correct
  argv++; argc--;       // AVOID!

7.2 复合语句(Compound Statements)

复合语句是包含在大括号中的语句序列,形如"{ 语句 }"。例如下面各段。

- 被括其中的语句应该较之复合语句缩进一个层次
- 左大括号"{"应位于复合语句起始行的行尾;右大括号"}"应另起一行并与复合语句首行对齐。
- 大括号可以被用于所有语句,包括单个语句,只要这些语句是诸如if-else或for控制结构的一部分。这样便于添加语句而无需担心由于忘了加括号而引入bug。

7.3 返回语句(return Statements)

一个带返回值的return语句不使用小括号"()",除非它们以某种方式使返回值更为显见。例如:

  return;

  return myDisk.size();

  return (size ? size : defaultSize);

7.4 if,if-else,if else-if else语句(if, if-else, if else-if else Statements)

if-else语句应该具有如下格式:

  if (condition) {
      statements;
  }

  if (condition) {
      statements;
  } else {
      statements;
  }

  if (condition) {
      statements;
  } else if (condition) {
      statements;
  } else{
      statements;
  }

注意:if语句总是用"{"和"}"括起来,避免使用如下容易引起错误的格式:

  if (condition) //AVOID! THIS OMITS THE BRACES {}!
      statement;

7.5 for语句(for Statements)

一个for语句应该具有如下格式:

  for (initialization; condition; update) {
      statements;
  }

一个空的for语句(所有工作都在初始化,条件判断,更新子句中完成)应该具有如下格式:

  for (initialization; condition; update);

当在for语句的初始化或更新子句中使用逗号时,避免因使用三个以上变量,而导致复杂度提高。若需要,可以在for循环之前(为初始化子句)或for循环末尾(为更新子句)使用单独的语句。

7.6 while语句(while Statements)

一个while语句应该具有如下格式

  while (condition) {
      statements;
  }

一个空的while语句应该具有如下格式:

  while (condition);

7.7 do-while语句(do-while Statements)

一个do-while语句应该具有如下格式:

  do {
      statements;
  } while (condition);

7.8 switch语句(switch Statements)

一个switch语句应该具有如下格式:

  switch (condition) {
  case ABC:
      statements;
      /* falls through */
  case DEF:
      statements;
      break;

  case XYZ:
      statements;
      break;

  default:
      statements;
      break;
  }

每当一个case顺着往下执行时(因为没有break语句),通常应在break语句的位置添加注释。上面的示例代码中就包含注释/* falls through */。

7.9 try-catch语句(try-catch Statements)

一个try-catch语句应该具有如下格式:

  try {
      statements;
  } catch (ExceptionClass e) {
      statements;
  }

一个try-catch语句后面也可能跟着一个finally语句,不论try代码块是否顺利执行完,它都会被执行。

  try {
      statements;
  } catch (ExceptionClass e) {
      statements;
  } finally {
      statements;
  }

8 空白(White Space)

8.1 空行(Blank Lines)

空行将逻辑相关的代码段分隔开,以提高可读性。

下列情况应该总是使用两个空行:

- 一个源文件的两个片段(section)之间
- 类声明和接口声明之间

下列情况应该总是使用一个空行:

- 两个方法之间
- 方法内的局部变量和方法的第一条语句之间
- 块注释(参见"5.1.1")或单行注释(参见"5.1.2")之前
- 一个方法内的两个逻辑段之间,用以提高可读性

8.2 空格(Blank Spaces)

下列情况应该使用空格:

- 一个紧跟着括号的关键字应该被空格分开,例如:

  while (true) {
      ...
  }

注意:空格不应该置于方法名与其左括号之间。这将有助于区分关键字和方法调用。
- 空白应该位于参数列表中逗号的后面
- 所有的二元运算符,除了".",应该使用空格将之与操作数分开。一元操作符和操作数之间不因该加空格,比如:负号("-")、自增("++")和自减("--")。例如:

    a += c + d;
    a = (a + b) / (c * d);

    while (d++ = s++) {
        n++;
    }
    printSize("size is " + foo + "\n");

- for语句中的表达式应该被空格分开,例如:

    for (expr1; expr2; expr3)

- 强制转型后应该跟一个空格,例如:

    myMethod((byte) aNum, (Object) x);
    myMethod((int) (cp + 5), ((int) (i + 3)) + 1);

9 命名规范(Naming Conventions)

命名规范使程序更易读,从而更易于理解。它们也可以提供一些有关标识符功能的信息,以助于理解代码,例如,不论它是一个常量,包,还是类。

标识符类型     命名规则     例子
包(Packages)     一个唯一包名的前缀总是全部小写的ASCII字母并且是一个顶级域名,通常是com,edu,gov,mil,net,org,或1981年ISO 3166标准所指定的标识国家的英文双字符代码。包名的后续部分根据不同机构各自内部的命名规范而不尽相同。这类命名规范可能以特定目录名的组成来区分部门(department),项目(project),机器(machine),或注册名(login names)。     com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
类(Classes)     命名规则:类名是个一名词,采用大小写混合的方式,每个单词的首字母大写。尽量使你的类名简洁而富于描述。使用完整单词,避免缩写词(除非该缩写词被更广泛使用,像URL,HTML)     class Raster;
class ImageSprite;
接口(Interfaces)     命名规则:大小写规则与类名相似     interface RasterDelegate;
interface Storing;
方法(Methods)     方法名是一个动词,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。     run();
runFast();
getBackground();
变量(Variables)     除了变量名外,所有实例,包括类,类常量,均采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。变量名不应以下划线或美元符号开头,尽管这在语法上是允许的。
变量名应简短且富于描述。变量名的选用应该易于记忆,即,能够指出其用途。尽量避免单个字符的变量名,除非是一次性的临时变量。临时变量通常被取名为i,j,k,m和n,它们一般用于整型;c,d,e,它们一般用于字符型。     char c;
int i;
float myWidth;
实例变量(Instance Variables)     大小写规则和变量名相似,除了前面需要一个下划线     int _employeeId;
String _name;
Customer _customer;
常量(Constants)     类常量和ANSI常量的声明,应该全部大写,单词间用下划线隔开。(尽量避免ANSI常量,容易引起错误)     static final int MIN_WIDTH = 4;
static final int MAX_WIDTH = 999;
static final int GET_THE_CPU = 1;

10 编程惯例(Programming Practices)

10.1 提供对实例以及类变量的访问控制(Providing Access to Instance and Class Variables)

若没有足够理由,不要把实例或类变量声明为公有。通常,实例变量无需显式的设置(set)和获取(gotten),通常这作为方法调用的边缘效应 (side effect)而产生。

一个具有公有实例变量的恰当例子,是类仅作为数据结构,没有行为。亦即,若你要使用一个结构(struct)而非一个类(如果java支持结构的话),那么把类的实例变量声明为公有是合适的。

10.2 引用类变量和类方法(Referring to Class Variables and Methods)

避免用一个对象访问一个类的静态变量和方法。应该用类名替代。例如:

  classMethod();             //OK
  AClass.classMethod();      //OK
  anObject.classMethod();    //AVOID!

10.3 常量(Constants)

位于for循环中作为计数器值的数字常量,除了-1,0和1之外,不应被直接写入代码。

10.4 变量赋值(Variable Assignments)

避免在一个语句中给多个变量赋相同的值。它很难读懂。例如:

  fooBar.fChar = barFoo.lchar = 'c'; // AVOID!

不要将赋值运算符用在容易与相等关系运算符混淆的地方。例如:

  if (c++ = d++) {        // AVOID! (Java disallows)
      ...
  }

应该写成

  if ((c++ = d++) != 0) {
    ...
  }

不要使用内嵌(embedded)赋值运算符试图提高运行时的效率,这是编译器的工作。例如:

  d = (a = b + c) + r;        // AVOID!

应该写成

  a = b + c;
  d = a + r;

10.5 其它惯例(Miscellaneous Practices)

10.5.1 圆括号(Parentheses)

一般而言,在含有多种运算符的表达式中使用圆括号来避免运算符优先级问题,是个好方法。即使运算符的优先级对你而言可能很清楚,但对其他人未必如此。你不能假设别的程序员和你一样清楚运算符的优先级。

  if (a == b && c == d)     // AVOID!
  if ((a == b) && (c == d))  // RIGHT

10.5.2 返回值(Returning Values)

设法让你的程序结构符合目的。例如:

  if (booleanExpression) {
      return true;
  } else {
      return false;
  }

应该代之以如下方法:

  return booleanExpression;

类似地:

  if (condition) {
      return x;
  }
  return y;

应该写做:

  return (condition ? x : y);

10.5.3 条件运算符"?"前的表达式(Expressions before '?' in the Conditional Operator)

如果一个包含二元运算符的表达式出现在三元运算符" ? : "的"?"之前,那么应该给表达式添上一对圆括号。例如:

  (x >= 0) ? x : -x;

10.5.4 特殊注释(Special Comments)

在注释中使用XXX来标识某些未实现(bogus)的但可以工作(works)的内容。用FIXME来标识某些假的和错误的内容。

11 代码范例(Code Examples)

11.1 Java源文件范例(Java Source File Example)

下面的例子,展示了如何合理布局一个包含单一公共类的Java源程序。接口的布局与其相似。更多信息参见"类和接口声明"以及"文挡注释"。

/*
* @(#)Blah.java        1.82 99/03/18
*
* Copyright (c) 1994-1999 Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information").  You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*/

package java.blah;

import java.blah.blahdy.BlahBlah;

/**
* Class description goes here.
*
* @version     1.82 18 Mar 1999
* @author     Firstname Lastname
*/
public class Blah extends SomeClass {
    /* A class implementation comment can go here. */

    /** classVar1 documentation comment */
    public static int classVar1;

    /**
     * classVar2 documentation comment that happens to be
     * more than one line long
     */
    private static Object classVar2;

    /** instanceVar1 documentation comment */
    public Object instanceVar1;

    /** instanceVar2 documentation comment */
    protected int instanceVar2;

    /** instanceVar3 documentation comment */
    private Object[] instanceVar3;

    /**
     * ...constructor Blah documentation comment...
     */
    public Blah() {
        // ...implementation goes here...
    }

    /**
     * ...method doSomething documentation comment...
     */
    public void doSomething() {
        // ...implementation goes here...
    }

    /**
     * ...method doSomethingElse documentation comment...
     * @param someParam description
     */
    public void doSomethingElse(Object someParam) {
        // ...implementation goes here...
    }
}

2008年1月20日

学做菜之甜椒肉丝

今天打算动手做一个甜椒肉丝。昨晚在老爸老妈的电话指导下知道了整个流程,想不到做这个菜居然还需要最后加芡汁。为了更加清楚,在网上找到如下介绍,想不到和爸妈说的几乎一模一样。佩服老爸老妈啊!今晚就按照这个做咯!

    * 【菜名】 甜椒肉丝
    * 【菜系】 川菜菜谱
    * 【主料】 猪肉
    * 【做法】 炒
    * 【味型】 清淡
    * 【成菜】 热菜

原料:猪肥瘦肉350克、甜椒100克、青蒜苗50克、嫩姜20克

调味料:水淀粉50克、盐少许、料酒20克、酱油10克、味精少许、鲜汤25克、甜酱20克

制作过程

1、猪肉切成粗丝,入碗加水淀粉、盐、料酒拌匀。

2、甜椒去蒂、籽,切成粗丝,嫩姜切细丝,蒜苗切小段。酱油、料酒、水淀粉、味精、鲜汤装碗内调匀成芡汁。

3、炒锅置火上,下油少许烧热,放入甜椒炒至断生后起锅。炒锅洗净置旺火上,下油烧热(约150℃,放肉丝炒散,加甜酱炒香,下甜椒、姜丝、青蒜苗合炒,烹入芡汁,炒匀起锅装盘即成。

美味小锦囊

◇青椒、红椒内含有维生素家族里知名度最高的维生素C,不过,人体无法贮存维生素C,别忘记时时补充、每天摄取!

◇肉丝在加水淀粉上浆前必须用清水充分浸泡,让肌肉纤维充分吸收水分、体形膨胀,并将带腥臊味的血浆完全泡出来。这样咸菜后色泽洁白、清爽不黏,还更加入味呢!

2008年1月18日

zz 如何参与团队合作

Link: http://www.mifengtd.cn/articles/how-to-participate-teamwork.html

现在,团队合作就是竞争力。随着市场竞争的日益激烈,企业更加强调团队精神,建立群体共识,以达到更高的工作效率。特别是有遇到大型项目时,想凭借一己之力去取得卓越的成果,可能非常困难。想必你也意识到,单打独斗的时代已经结束了,取而代之的真是团队合作!

团队的组成不是一个人,如何融入团队,和其它成员共同努力、精诚协助是件看起来很容易的事情,可事实却大相径庭。团队,除了要依靠卓越的领导者,每个成员都是使团队不断融合不可或缺的一份子。

打造一支高效的团队绝非一朝一夕之事,希望下面的一些建议能够帮助你更好的融入团队,积极参加团队合作。


领导者

领导者是团队的核心,是从全局角度把握整个团队方向的人。作为一个领导者,虽然你的权威级别是高一些,不过学会熟练地与别人一起完成更多的工作,都应该是为提示自身价值所能做的最重要的事。

    * 分工明确但不呆板明确的分工可以让每一位成员清楚的知道自己要做什么,什么时候做完,做到什么承度。这样就能够避免由于分工不明确而造成的部分人员闲置的问题。如果你还不太清楚怎样进行分工,那么你可以尝试给每一个任务都指定一个负责人,这是最简单的方法了。这里强调不能呆板的意思是说,当分工确定后,如果某一任务的负责人员遇到了某种困难而无法按期完成的时候,应该适当的调整分工或者让其它成员帮助他们完成。不要死守原来的分工。
    * 加强团队成员的日常交流不时的安排一些聚会或者组织素质拓展训练,一起吃饭,打打球,都是很好的加强团队成员间交流的方法。不要小看这一点,这是非常重要的。团队成员的日常交流可以让他们更加亲近,从而在工作中更容易进行合作。如果平时他们之间就有默契的话,在工作时的表现就更容易提高。
    * 说话时多使用我们在你说话的时候多使用我们这个代词,不要使用我、你、他或者直呼姓名,也要鼓励你的团队成员也这样做。这样可以帮助你的团队成员们形成一种集体意识,让他们从团队的角度去想问题,而不是总从自己出发。
    * 让每个人感觉到自己很重要你要让你团队中的每一个人都感到自己很重要,这样他们做事才会更有成就感,也更有紧迫感。一个人一旦觉得自己不重要,往往会非常沮丧,从而失去激情,这会导致工作效率和创造力的显著下降。

团队成员

每个团队成员都是不可或缺的,而且每一个团队成员都要具有团队合作的意识。无论你自身能力的强大,团队少了你依然会继续运行,所以不要枉自称大。

    * 做好自己的事情团队合作中,最起码的事情就是把自己的事情做好。团队的任务都是有分工的,分配给自己的任务就要按时做好。只有这样,你才能不给别人带来麻烦;也只有在这个前提下,你才能去帮助其他成员的事情,否则你就有些轻重不分了。
    * 信任你的伙伴既是团队成员,就要相信自己的伙伴,相信他们能够与你协调一致,相信他们会理解你,支持你。一个团队只有在信任的氛围中才可能有高效的工作。如果大家相互猜忌、互不信任,那么分工就不可能,因为总有一些任务依赖于别的任务;同时猜忌的气氛让每一个人都不能全心投入到工作中去,也不利于成员们工作能力的发挥。
    * 为他人着想不要事事都从自己的角度考虑。如果有任何问题或者遇到什么问题,先从别人的角度想一想,看看怎样能让他人更加方便。这样的人在团队当中会很受欢迎,同时也更有亲和力,而亲和力对于团队合作来说是很重要的。
    * 愿意多付出付出并不是什么坏事。多做一些,可以让团队的工作进展更快,你也得到更多的好评,能力上也有提高,何乐而不为呢?当然也不是付出的越多越好,如果所有的事都让你自己做了(虽然这一般是不可能的),其它的人一定会有意见的。

2008年1月17日

项目管理之甘特图

缘起:

        从明天开始,我将进入一个新的工作阶段,时间较长(两个月),目标确定,为了进行有效的时间管理以及任务分配,我打算采用软件工程的方法来进行管理。首先想到的就是甘特图。因为我指导的学生Zn,在上个月发给我他的个人项目计划时展示了一张甘特图,时间管理上非常清晰。回想自己大四的时候学习过这个东西,但是一直没有试验过。这次打算小试一下。

 

什么是甘特图:

甘特图(Gantt Chart)由亨利·甘特于1910年开发的,他通过条状图来显示项目,进度,和其他时间相关的系统进展的内在关系随着时间进展的情况。 其中,横轴表示时间,纵轴表示活动(项目)。线条表示在整个期间上计划和实际的活动完成情况。甘特图可以直观地表明任务计划在什么时候进行,及实际进展与计划要求的对比。管理者由此可以非常便利地弄清每一项任务(项目)还剩下哪些工作要做,并可评估工作是提前还是滞后,亦或正常进行。除此以外,甘特图还有简单、醒目和便于编制等特点。所以,甘特图对于项目管理是一种理想的控制工具。

甘特图的含义:

   1. 以图形或表格的形式显示活动;
   2. 现在是一种通用的显示进度的方法;
   3. 构造时应包括实际日历天和持续时间,并且不要将周末和节假日算在进度之内。

下面使用一个例子来简单说明甘特图:

时间以月为单位表示在图的下方,主要活动从上到下列在图的左边。计划需要确定数的出版包括哪些活动,这些活动的顺序,以及每项活动持续的时间。时间框里的线条表示计划的活动顺序,空白的现况表示活动的实际进度。甘特图作为一种控制工具,帮助管理者发现实际进度偏离计划的情况。在本例中,除了打印长条校样以外,其他活动都是按计划完成的。

甘特图的优点:

    * 图形化概要,通用技术,易于理解;
    * 中小型项目一般不超过30项活动;
    * 有专业软件支持,无须担心复杂计算和分析。

甘特图的局限:

    * 甘特图事实上仅仅部分地反映了项目管理的三重约束(时间、成本和范围),因为它主要关注进程管理(时间);
    * 软件的不足。尽管能够通过项目管理软件描绘出项目活动的内在关系,但是如果关系过多,纷繁芜杂的线图必将增加甘特图的阅读难度;
    * 为了不至于转移阅读者的注意力,还最好避免使用栅格。

另外,个人甘特图与平常我们使用的时间表是两种不同的任务表达方式。个人甘特图使用户可以直观地知道有哪些任务在什么时间段要做,而时间表则提供更精确的时间段数据。此外,用户还可以在时间表中直接更新任务进程。

制作甘特图的方法,有专门的软件如Ganttproject、Gantt Designer和Microsoft Project等等。当然你还可以在Microsoft Excel中手动绘制。这些弥缝将会在下次介绍。

 

甘特图(Gantt Chart)的制作步骤:

在开始介绍甘特图的制作步骤前,弥缝先向大家讲解一下什么是Work Breakdown Structure(WBS):

    WBS就是工作分解结构,就象一张道路交通图,它能够指引你如何从当前位置到达想去的地方。

因此,就有这么两个对于任务区分的概念:依赖性活动(Sequential activities)和决定性活动(Parallel activities)。有些任务需要一层一层的来完成,你需要先完成一项任务,才能继续下一项任务,这就是依赖性活动。而决定性活动则是指并不需要某一项任务结束后,就能开始的任务。

绘制甘特图的步骤:

   1. 明确项目牵涉到的各项活动、项目。内容包括项目名称(包括顺序)、开始时间、工期,任务类型(依赖/决定性)和依赖于哪一项任务。
   2. 创建甘特图草图。将所有的项目按照开始时间、工期标注到甘特图上。
   3. 确定项目活动依赖关系及时序进度。使用草图,并且按照项目的类型将项目联系起来,并且安排。
          * 此步骤将保证在未来计划有所调整的情况下,各项活动仍然能够按照正确的时序进行。
          * 也就是确保所有依赖性活动能并且只能在决定性活动完成之后按计划展开。
          * 避免关键性路径过长。关键性路径是由贯穿项目始终的关键性任务所决定的,它既表示了项目的最长耗时, 也表示了完成项目的最短可能时间。请注意,关键性路径会由于单项活动进度的提前或延期而发生变化。
          * 不要滥用项目资源,同时,对于进度表上的不可预知事件要安排适当的富裕时间(Slack Time)。 但是,富裕时间不适用于关键性任务,因为作为关键性路径的一部分,它们的时序进度对整个项目至关重要。
   4. 计算单项活动任务的工时量。
   5. 确定活动任务的执行人员及适时按需调整工时。
   6. 计算整个项目时间。专业性软件可以自动完成该项工作。

 

软件支持:

首推GanttProject,因为开源,而且经过实践,确实非常的方便,可以参见Demo

2008年1月16日

Python提高建议(Python Enhancement Proposals)

今天发现了Python的一个提高编程技能的系列文章,是Python.org网站上提供的。仔细一看,足足有224篇,全都是Python的大牛们的撰写,想不到不是任何文章这里都收录的,居然还有像论文发表那样的流程:

有空得多读读啊,也算是对自己编程能力的一种训练吧。哎!俺现在的编程技巧很混乱,不系统啊。

 

差点忘了添加链接:

Index of Python Enhancement Proposals (PEPs)

2008年1月15日

Learning Epydoc

Epydoc 是什么,Epydoc好吃么?呵呵,这个是Zn在Lilacbbs上留言的模板 :)

先看看这个东西是什么,有什么用,为什么一定要学它?

Epydoc是一个用于Python模块自动生成API文档的工具,主要基于Python模块的文档字符串(docstring),例如Epydoc本省的API文档(html)。一种名叫Epytext轻量级的标记语言被用来标记各种文档字符串,主要是在一些特定的标签上添加相关的信息,例如参数类型等等。Epydoc还可以接受reStructureText,Javadoc以及普通文本格式的docstring。更精彩的例子推荐NLTK的官方API文档

Epydoc 是纯Python 实现的 Python 专用文档化工具,与Python 结合非常自然,稳定,可扩展,Python代码中的注释采用Epydoc规定的格式来撰写可以非常方便的生成程序的规范化API文档。可以说Epydoc是采用Python按照软件工程开发步骤中不可缺少的一环。

熟悉Python的朋友知道Python还有一个类似的工具可以使用,那就是Pydoc。它和Epydoc的关系是后者能够生成更加丰富和漂亮的文档。

 

下面说说怎么用Epydoc。在网上找了半天,也没有看到一个好的中文资料介绍如何使用这个工具。分为以下几步:

1.安装,参见英文版说明

sf上下载并安装epydoc-3.0beta1.win32.exe

2.在代码中插入相关的各种格式的Docstring,例如下列标签:

py文献信息

@author: ...作者
@license: ...版权
@contact: ...联系

py状态信息
@version: ...版本推荐使用$Id$
@todo [ver]: ...改进,可以指定针对的版本

py模块信息
@var v: ...模块变量v说明
@type v: ...模块变量类型v说明

py函式信息

@param p: ...参数 p 说明
@type v: ...参数 p 类型说明
@return: ...返回值说明
@rtype v: ...返回值类型说明

py提醒信息

@note: ...注解
@attention: ...注意
@bug: ...问题
@warning: ...警告

py关联信息
@see: ...参考资料

py标签格式
@tag: 内容...

还可以插入url,交叉引用,分块等功能,参见文档化开发注释规范

3.相关工具推荐

现在最喜欢使用的Python IDE是Eclipse + Pydev,今天发现Pydev的Code Style里面可以针对Docstring进行设置,弄好后在编写代码的时候,适当的用Ctrl+1就可以获得自动的Docstring内容,再添加一些就能生成良好的文档了。

4.生成API文档的时候推荐使用GUI方式,省时省力。点击Pydoc安装文档下的gui.py即可。

 

如果是其他的编程语言推荐使用Doxygen,支持C++, C, Java, Objective-C, IDL (Corba and Microsoft flavors) 以及PHP, C# and D 等等语言。

 

总之,我是离不开这个东东了。

2008年1月14日

Python的敏捷工具箱[转]

 

Pycon2006的有一篇Paper是介绍如果使用敏捷的开发和测试方法进行Python开发。其中,包括的内容是我到目前为止看到的最全面的Agile Toolkits介绍:

1. Source control management ( subversion) and issue tracking/project management ( Trac)

2. TDD/unit testing ( py.test,  doctest,  noseTestOOB)

3.  unit tests as documentation ( doctest and epydoc)

4. code coverage (the  coverage module)

5. source code analysis ( pylint,  pyflakes, pychecker)

6. acceptance/functional testing ( PyFit/FitNesse,  TextTest)

7. performance testing ( FunkLoadtwill)

8. Web application testing with  Selenium and twill

9. Scripting Selenium tests using a  Twisted-based server

10. Python package management ( distutils,  setuptoolsCheesecake index)

11. Continuous integration and 'smoke test' ( buildbot )

2008年1月13日

见贤思齐之工作日志

近日来,我的生活规律比较混乱。为了调参数以及加入各种相关特征到我自认为最好的ILP框架里,每天睡得晚,起得晚,效率较为低下。唯一坚持到底的生活规律就只剩下每天早上煮粥了 :)

前不久,我开始安排我指导的几位同学每日发送工作日报给我,理由是对他们的工作能够形成良好的督促,并且能提高他们的效率。这个办法是从忻舟那里学来的,他从百度实习三个月回来后每日主动给我发送报告,对我也形成了一定的督促。

见贤思齐,我打算今天开始采用这种方式来进行我自己的个人每日工作管理。(提起见贤思齐,我想起了我的师姐Simply,感谢她的教诲)

基本的模板如下,每日早上填写一些,晚上再填写一些,然后离开实验室时发给Mentor。

----------------------------------------------------------------

项目名称

所花时间

项目内容

影响效率的原因
其他

明天计划

----------------------------------------------------------------

考虑到撰写在电脑里面会在更换电脑或者工作地点时不便查阅,我想到将我的工作日志写在Google Notebook里面。希望借助于此更变自己目前的状态。

2008年1月7日

zz Zhihua Zhou所写的"对AI领域的会议的评点"

对AI领域的会议的评点
注: 本文为小百合BBS的daniel所写
The First Class:
今天先谈谈AI里面tier-1的conferences, 其实基本上就是AI里面大家比较公认的top conference. 下面同分的按字母序排列.

IJCAI (1+): AI最好的综合性会议, 1969年开始, 每两年开一次, 奇数年开. 因为AI实在太大, 所以虽然每届基本上能录100多篇(现在已经到200多篇了),但分到每个领域就没几篇了,象machine learning、computer vision这么大的领域每次大概也就10篇左右, 所以难度很大. 不过从录用率上来看倒不太低,基本上20%左右, 因为内行人都会掂掂分量, 没希望的就别浪费reviewer的时间了. 最近中国大陆投往国际会议的文章象潮水一样, 而且因为国内很少有能自己把关的研究组, 所以很多会议都在complain说中国的低质量文章严重妨碍了PC的工作效率. 在这种情况下, 估计这几年国际会议的录用率都会降下去. 另外, 以前的IJCAI是没有poster的, 03年开始, 为了减少被误杀的好人, 增加了2页纸的poster.值得一提的是, IJCAI是由貌似一个公司的"IJCAI Inc."主办的(当然实际上并不是公司, 实际上是个基金会), 每次会议上要发几个奖, 其中最重要的两个是IJCAI Research Excellence Award 和 Computer
& Thoughts Award, 前者是终身成就奖, 每次一个人, 基本上是AI的最高奖(有趣的是, 以AI为主业拿图灵奖的6位中, 有2位还没得到这个奖), 后者是奖给35岁以下的青年科学家, 每次一个人. 这两个奖的获奖演说是每次IJCAI的一个重头戏.另外, IJCAI 的 PC member 相当于其他会议的area chair, 权力很大, 因为是由PC member去找 reviewer 来审, 而不象一般会议的PC member其实就是 reviewer. 为了制约这种权力, IJCAI的审稿程序是每篇文章分配2位PC member, primary PC member去找3位reviewer, second PC member 找一位.

AAAI (1): 美国人工智能学会AAAI的年会. 是一个很好的会议, 但其档次不稳定, 可以给到1+, 也可以给到1-或者2+, 总的来说我给它"1". 这是因为它的开法完全受IJCAI制约: 每年开, 但如果这一年的IJCAI在北美举行, 那么就停开. 所以, 偶数年里因为没有IJCAI, 它就是最好的AI综合性会议, 但因为号召力毕竟比IJCAI要小一些, 特别是欧洲人捧AAAI场的比IJCAI少得多(其实亚洲人也是), 所以比IJCAI还是要稍弱一点, 基本上在1和1+之间; 在奇数年, 如果IJCAI不在北美, AAAI自然就变成了比IJCAI低一级的会议(1-或2+), 例如2005年既有IJCAI又有AAAI, 两个会议就进行了协调, 使得IJCAI的录用通知时间比AAAI的deadline早那么几天, 这样IJCAI落选的文章可以投往AAAI.在审稿时IJCAI 的 PC chair也在一直催, 说大家一定要快, 因为AAAI那边一直在担心IJCAI的录用通知出晚了AAAI就麻烦了.

COLT (1): 这是计算学习理论最好的会议, ACM主办, 每年举行. 计算学习理论基本上可以看成理论计算机科学和机器学习的交叉, 所以这个会被一些人看成是理论计算机科学的会而不是AI的会. 我一个朋友用一句话对它进行了精彩的刻画: "一小群数学家在开会". 因为COLT的领域比较小, 所以每年会议基本上都是那些人. 这里顺便提一件有趣的事, 因为最近国内搞的会议太多太滥, 而且很多会议都是LNCS/LNAI出论文集, LNCS/LNAI基本上已经被搞臭了, 但很不幸的是, LNCS/LNAI中有一些很好的会议, 例如COLT.

CVPR (1): 计算机视觉和模式识别方面最好的会议之一, IEEE主办, 每年举行. 虽然题目上有计算机视觉, 但个人认为它的模式识别味道更重一些. 事实上它应该是模式识别最好的会议, 而在计算机视觉方面, 还有ICCV与之相当. IEEE一直有个倾向, 要把会办成"盛会", 历史上已经有些会被它从quality很好的会办成"盛会"了. CVPR搞不好也要走这条路. 这几年录的文章已经不少了. 最近负责CVPR会议的TC的chair发信说, 对这个community来说, 让好人被误杀比被坏人漏网更糟糕, 所以我们是不是要减少好人被误杀的机会啊? 所以我估计明年或者后年的CVPR就要扩招了.

 

ICCV (1): 介绍CVPR的时候说过了, 计算机视觉方面最好的会之一. IEEE主办, 每年举行.

ICML (1): 机器学习方面最好的会议之一. 现在是IMLS主办, 每年举行. 参见关于NIPS的介绍.

NIPS (1): 神经计算方面最好的会议之一, NIPS主办, 每年举行. 值得注意的是, 这个会每年的举办地都是一样的, 以前是美国丹佛, 现在是加拿大温哥华; 而且它是年底开会,会开完后第2年才出论文集, 也就是说, NIPS'05的论文集是06年出. 会议的名字是"Advances in Neural Information Processing Systems", 所以, 与ICML\ECML这样的"标准的"机器学习会议不同, NIPS里有相当一部分神经科学的内容, 和机器学习有一定的距离. 但由于会议的主体内容是机器学习, 或者说与机器学习关系紧密, 所以不少人把NIPS看成是机器学习方面最好的会议之一. 这个会议基本上控制在Michael Jordan的徒子徒孙手中, 所以对Jordan系的人来说, 发NIPS并不是难事, 一些未必很强的工作也能发上去, 但对这个圈子之外的人来说, 想发一篇实在很难, 因为留给"外人"的口子很小. 所以对Jordan系以外的人来说, 发NIPS的难度比ICML更大. 换句话说,
ICML比较开放, 小圈子的影响不象NIPS那么大, 所以北美和欧洲人都认, 而NIPS则有些人(特别是一些欧洲人, 包括一些大家)坚决不投稿. 这对会议本身当然并不是好事, 但因为Jordan系很强大, 所以它似乎也不太care. 最近IMLS(国际机器学习学会)改选理事, 有资格提名的人包括近三年在ICML\ECML\COLT发过文章的人, NIPS则被排除在外了. 无论如何, 这是一个非常好的会.

ACL (1-): 计算语言学/自然语言处理方面最好的会议, ACL (Association of Computational Linguistics) 主办, 每年开.

KR (1-): 知识表示和推理方面最好的会议之一, 实际上也是传统AI(即基于逻辑的AI)最好的会议之一. KR Inc.主办, 现在是偶数昕?

SIGIR (1-): 信息检索方面最好的会议, ACM主办, 每年开. 这个会现在小圈子气越来越重. 信息检索应该不算AI, 不过因为这里面用到机器学习越来越多, 最近几年甚至有点机器学习应用会议的味道了, 所以把它也列进来.

SIGKDD (1-): 数据挖掘方面最好的会议, ACM主办, 每年开. 这个会议历史比较短, 毕竟, 与其他领域相比,数据挖掘还只是个小弟弟甚至小侄儿. 在几年前还很难把它列在tier-1里面, 一方面是名声远不及其他的top conference响亮, 另一方面是相对容易被录用. 但现在它被列在tier-1应该是毫无疑问的事情了. 另: 参见sir和lucky的介绍.

UAI (1-): 名字叫"人工智能中的不确定性", 涉及表示\推理\学习等很多方面, AUAI (Association of UAI) 主办, 每年开.

 

The Second Class:
tier-2的会议列得不全, 我熟悉的领域比较全一些.

AAMAS (2+): agent方面最好的会议. 但是现在agent已经是一个一般性的概念, 几乎所有AI有关的会议上都有这方面的内容, 所以AAMAS下降的趋势非常明显.

ECCV (2+): 计算机视觉方面仅次于ICCV的会议, 因为这个领域发展很快, 有可能升级到1-去.

ECML (2+): 机器学习方面仅次于ICML的会议, 欧洲人极力捧场, 一些人认为它已经是1-了. 我保守一点, 仍然把它放在2+. 因为机器学习发展很快, 这个会议的reputation上升非常明显.

ICDM (2+): 数据挖掘方面仅次于SIGKDD的会议, 目前和SDM相当. 这个会只有5年历史, 上升速度之快非常惊人. 几年前ICDM还比不上PAKDD, 现在已经拉开很大距离了.

SDM (2+): 数据挖掘方面仅次于SIGKDD的会议, 目前和ICDM相当. SIAM的底子很厚, 但在CS里面的影响比ACM和IEEE还是要小, SDM眼看着要被ICDM超过了, 但至少目前还是相当的.

ICAPS (2): 人工智能规划方面最好的会议, 是由以前的国际和欧洲规划会议合并来的. 因为这个领域逐渐变冷清, 影响比以前已经小了.

ICCBR (2): Case-Based Reasoning方面最好的会议. 因为领域不太大, 而且一直半冷不热, 所以总是停留在2上.

COLLING (2): 计算语言学/自然语言处理方面仅次于ACL的会, 但与ACL的差距比ICCV-ECCV和ICML-ECML大得多.

ECAI (2): 欧洲的人工智能综合型会议, 历史很久, 但因为有IJCAI/AAAI压着, 很难往上升.

ALT (2-): 有点象COLT的tier-2版, 但因为搞计算学习理论的人没多少, 做得好的数来数去就那么些group, 基本上到COLT去了, 所以ALT里面有不少并非计算学习理论的内容.

EMNLP (2-): 计算语言学/自然语言处理方面一个不错的会. 有些人认为与COLLING相当, 但我觉得它还是要弱一点.

ILP (2-): 归纳逻辑程序设计方面最好的会议. 但因为很多其他会议里都有ILP方面的内容, 所以它只能保住2-的位置了.

PKDD (2-): 欧洲的数据挖掘会议, 目前在数据挖掘会议里面排第4. 欧洲人很想把它抬起来, 所以这些年一直和ECML一起捆绑着开, 希望能借ECML把它带起来. 但因为ICDM和SDM, 这已经不太可能了. 所以今年的PKDD和ECML虽然还是一起开, 但已经独立审稿了(以前是可以同时投两个会, 作者可以声明优先被哪个会考虑, 如果ECML中不了还可以被PKDD接受).


The Third Class:
列得很不全. 另外, 因为AI的相关会议非常多, 所以能列在tier-3也算不错了, 基本上能进到所有AI会议中的前30%吧

ACCV (3+): 亚洲的计算机视觉会议, 在亚太级别的会议里算很好的了.

DS (3+): 日本人发起的一个接近数据挖掘的会议.

ECIR (3+): 欧洲的信息检索会议, 前几年还只是英国的信息检索会议.

ICTAI (3+): IEEE最主要的人工智能会议, 偏应用, 是被IEEE办烂的一个典型. 以前的quality还是不错的, 但是办得越久声誉反倒越差了, 糟糕的是似乎还在继续下滑, 现在其实3+已经不太呆得住了.

PAKDD (3+): 亚太数据挖掘会议, 目前在数据挖掘会议里排第5.

ICANN (3+): 欧洲的神经网络会议, 从quality来说是神经网络会议中最好的, 但这个领域的人不重视会议,在该领域它的重要性不如IJCNN.

AJCAI (3): 澳大利亚的综合型人工智能会议, 在国家/地区级AI会议中算不错的了.

CAI (3): 加拿大的综合型人工智能会议, 在国家/地区级AI会议中算不错的了.

CEC (3): 进化计算方面最重要的会议之一, 盛会型. IJCNN/CEC/FUZZ-IEEE这三个会议是计算智能或者说软计算方面最重要的会议, 它们经常一起开, 这时就叫WCCI (World Congress on Computational Intelligence). 但这个领域和CS其他分支不太一样, 倒是和其他学科相似, 只重视journal, 不重视会议, 所以录用率经常在85%左右, 所录文章既有quality非常高的论文, 也有入门新手的习作.

FUZZ-IEEE (3): 模糊方面最重要的会议, 盛会型, 参见CEC的介绍.

GECCO (3): 进化计算方面最重要的会议之一, 与CEC相当,盛会型.

ICASSP (3): 语音方面最重要的会议之一, 这个领域的人也不很care会议.

ICIP (3): 图像处理方面最著名的会议之一, 盛会型.

ICPR (3): 模式识别方面最著名的会议之一, 盛会型.

IEA/AIE (3): 人工智能应用会议. 一般的会议提名优秀论文的通常只有几篇文章, 被提名就已经是很高的荣誉了, 这个会很有趣, 每次都搞1、20篇的优秀论文提名, 专门搞几个session做被提名论文报告, 倒是很热闹.

IJCNN (3): 神经网络方面最重要的会议, 盛会型, 参见CEC的介绍.

IJNLP (3): 计算语言学/自然语言处理方面比较著名的一个会议.

PRICAI (3): 亚太综合型人工智能会议, 虽然历史不算短了, 但因为比它好或者相当的综合型会议太多, 所以很难上升.

 

Combined List:
说明: 纯属个人看法, 仅供参考. tier-1的列得较全, tier-2的不太全, tier-3的很不全.同分的按字母序排列. 不很严谨地说, tier-1是可以令人羡慕的, tier-2是可以令人尊敬的,由于AI的相关会议非常多, 所以能列进tier-3的也是不错的

tier-1:
IJCAI (1+): International Joint Conference on Artificial Intelligence
AAAI (1): National Conference on Artificial Intelligence
COLT (1): Annual Conference on Computational Learning Theory
CVPR (1): IEEE International Conference on Computer Vision and Pattern Recognition
ICCV (1): IEEE International Conference on Computer Vision
ICML (1): International Conference on Machine Learning
NIPS (1): Annual Conference on Neural Information Processing Systems
ACL (1-): Annual Meeting of the Association for Computational Linguistics
KR (1-): International Conference on Principles of Knowledge Representation and Reasoning
SIGIR (1-): Annual International ACM SIGIR Conference on Research and Development in Information Retrieval
SIGKDD (1-): ACM SIGKDD International Conference on Knowledge Discovery and Data Mining
UAI (1-): International Conference on Uncertainty in Artificial Intelligence


tier-2:
AAMAS (2+): International Joint Conference on Autonomous Agents and Multiagent Systems
ECCV (2+): European Conference on Computer Vision
ECML (2+): European Conference on Machine Learning
ICDM (2+): IEEE International Conference on Data Mining
SDM (2+): SIAM International Conference on Data Mining
ICAPS (2): International Conference on Automated Planning and Scheduling
ICCBR (2): International Conference on Case-Based Reasoning
COLLING (2): International Conference on Computational Linguistics
ECAI (2): European Conference on Artificial Intelligence
ALT (2-): International Conference on Algorithmic Learning Theory
EMNLP (2-): Conference on Empirical Methods in Natural Language Processing
ILP (2-): International Conference on Inductive Logic Programming
PKDD (2-): European Conference on Principles and Practice of Knowledge Discovery in Databases

tier-3:
ACCV (3+): Asian Conference on Computer Vision
DS (3+): International Conference on Discovery Science
ECIR (3+): European Conference on IR Research
ICTAI (3+): IEEE International Conference on Tools with Artificial Intelligence
PAKDD (3+): Pacific-Asia Conference on Knowledge Discovery and Data Mining
ICANN (3+): International Conference on Artificial Neural Networks
AJCAI (3): Australian Joint Conference on Artificial Intelligence
CAI (3): Canadian Conference on Artificial Intelligence
CEC (3): IEEE Congress on Evolutionary Computation
FUZZ-IEEE (3): IEEE International Conference on Fu Systems
GECCO (3): Genetic and Evolutionary Computation Conference
ICASSP (3): International Conference on Acoustics, Speech, and Signal Processing
ICIP (3): International Conference on Image Processing
ICPR (3): International Conference on Pattern Recognition
IEA/AIE (3): International Conference on Industrial and Engineering Applications of Artificial Intelligence and Expert Systems
IJCNN (3): International Joint Conference on Neural Networks
IJNLP (3): International Joint Conference on Natural Language Processing
PRICAI (3): Pacific-Rim International Conference on Artificial Intelligence

2008年1月4日

艰难时刻:绝处?尚未逢生

       近来一直忙于ILP用于代词消解,几个月的工作就在快要ACL截稿时发现结果并不是很好,距离自己构建好的baseline系统的结果还差一点。Baseline现在得到的结果是93%,而ILP的结果经过昨天一天的debug,达到了89%。

      

      今天采用了我能想到的最后一招:拓展ILP谓词语句中的一个词性和词汇的绑定。使得学习能力以及泛化能力得到进一步的增强。这个是昨天晚上仔细翻看自己写的一些报告内容才想到的。但愿能使我绝处逢生。

      想用好ILP还真是不容易啊。万事开头难,必须挺住!为自己加把油。

2008年1月3日

Learn English from VOA Special English

以前学习过钟道隆介绍的逆向英语学习法,其中主要就是采用了VOA Special English来进行不断的练习。当时觉得是很好的方法,但是没有坚持下来。

美国著名词汇学家 S. B. Flexmer 指明了 Special English 的三条标准,也就是它所 “ 特别 ” 的地方:

1. 它是一种由美国人最常用的 1500 个基本单词为主体构成的美国英语;

2. 它用简短、明晰的句子写作和广播;

3. 它以每分钟 90 个单词的速度,即 2/3 的 Standard English (常速英语)速度进行广播。

 

今天在使用Lingoes第二版时发现其中有VOA Special English的链接,上网查了一下究竟该如何采用这个东西来练习英语。结论如下(很长):

-------------------------------------------------------------

VOA Special English 节目内容题材广泛,如果能坚持长期学习,你不仅能扩充知识面,增加词汇量,提高阅读能力,还能在潜移默化中提高写作水平。那么你是怎么样使用 VOA Special English 来学习提高英语水平的呢?

这次讨论的目的在于发现常见的错误的学习方法,总结出一套行之有效的最佳 VOA Special English 学习方法,欢迎大学积极参与讨论!

-------------------------------

最佳实践一:用 VOA Special English 练听力

网站上提供的 VOA Special English 节目文本是配有MP3声音的,声音文件由美国本土资深专业播音员录制,如果想有效提高自己的英语听力,VOA Special English 节目资料将是非常好的听力练习素材。而最快最有效的提高英语听力的方法就是做听写,怎么听呢?下面分几个层次介绍听写的方法。

(一)初级英语水平学生(相当于高中英语水平)做听写的方法

1、从 http://www.unsv.com/ 网站下载一个 5 分钟的 report 到电脑里(包括下载report的MP3录音和文本),准备好一本英汉词典或电子词典(UNSV.COM网站廉价销售英汉双译电子词典:新一代诺亚舟双译王 ND316+,售价¥388元)。

2、认真阅读report文本一至两遍,遇到不懂的单词请立即查词典。

3、将文本放在一边,开始听report的MP3录音,并将听到的写下来,就是做听写练习。一直循环播放,尽可能的将自己能听写出来的,全部写出来。

4、将自己的听写稿和原稿对照,找出没有听写出来的词句,并标上记号,这些没有听出来的词句可能很简单,但事实是你没有听写出来,这些就是你听力的盲点,所以要特别留意。

5、再反复地听report的MP3录音,这次不用纸笔听写,而是在脑袋里做听写,就是指当你听到一句的时候,脑袋里把这一句给拼出来,确保听清每一个词句,并留意你在听写时没有写出来的词句的发音。

6、第二天再听上面的report的MP3录音,并采用上面第5点所用的听法。第四天再听上面的report的MP3录音,等到第七天再听几篇,仍采用上面第5点所用的听法。为什么要反复地听?因为我们之所以听不懂,是因为听的太少了。反复听的目的在于强化,让你形成一种听力条件反射,就是让你拥有一听到某些词句就能立即条件反射式地在脑袋里写出来你所听到的词句。

练习听力有点像练习电脑打字里的盲打,花时间多做练习自然就会盲打,如果只是想着如何学习盲打而不加以练习,那你永远也学不会盲打。

(二)中级英语水平学生(相当于非英语专业大学本科,硕士水平)做听写的方法

基本方法与初级英语水平学生采用的方法类似,采用上述方法的1、3、4、5、6条的顺序做听写练习。

最佳实践二:用 VOA Special English 训练出纯正英语发音和表达

当你在听中文学得还不错的外国人讲中文时,经常觉得听上去很别扭,因为他的发音和句式让我们觉得很不习惯。同样,一个英语水平还不错的中国人在讲英语时,也存在中式英语发音和句式方面的问题。

如果你也存在英语发音不准、句式偏中文化会让英语母语国家人士难以理解你所说的,导致语言交流困难。那么,该如何合理地使用 VOA Special English 学习资料来帮助我们训练出纯正的英语发音和表达呢?下面是一个经过实践反馈具体最佳训练效果的方法。

1、从www.unsv.com下载一个 VOA Special English 节目的 mp3 录音和配套文本到电脑里或MP3播放器里;

2、先不要播放mp3录音,而是自己当一次播音主持,对着节目文本,大声的朗读,并录制到电脑或其它可以录制声音的设备里;

3、循环播放自己的录音,并对照节目的正式mp3录音,认真找出自己的在单词发音和句子升降调、轻重发音方面的问题;

4、认真阅读节目文本,学习表达事物、情感等用到的各类句式。对于常用的句式,自已也可以模仿造几个句子,加深理解。

VOA Special English 节目里的所有 short report(5分钟的) 和 feature report(15分钟)的一般都可以做为训练素材,特别是 Words and Their Stories 和 American Stories 最佳,这是因为 Words and Their Stories 和 American Stories 是讲故事性质的,主持人在播读这两个专题时更富有感情色彩。

-------------------------------

 

另外找到沪江英语网站上有在线的每日Special学习,感觉非常适合我这样的“懒人”来不断受督促学习。

link: 慢速VOA每日听写