存档

作者存档

如果不能在8小时内完成工作,哪来时间加班?

2012年1月29日 没有评论

如果不能在8小时内完成工作,哪来时间加班?

“如果不能在8小时内完成工作,哪来时间加班?”

“如果有一项重要又紧急的任务,那就交个最忙的那个人吧”

前言

本文是看知乎上某答案时有感而发,更多的是对工作的看法的积累,总结出来,一吐为快。

知乎上有人问腾讯的核心竞争力,得票最高的答案是腾讯某产品总监给出的,其中提到努力是其中之一,案例就是晚上加班到1点钟。链接:腾讯这家公司的核心竞争力是什么?

我没有否定该观点的想法,只是对于工作到1点保留自己的看法。

标题解释

标题中的问题很有争议性,正文开头的观点也很偏激。稍微解释一下,这两句话字面意思不代表我真实的看法,只不过符合看问题的角度而已。

对加班的看法

关于加班的第一个看法:“如果不能在8小时内完成工作,哪来时间加班?

一句话终究还是太短,漏洞百出,补充说明一下

  1. 这里说的不能在8小时内完成工作是指频繁加班,而不是偶尔,例如每个季度3次加班到深夜这种零星的肯定不算

  2. 更多的是指一线员工,俗称干事,严肃点叫非管理人员,管理者因为职责特殊性,工作时间可能不太稳定。但是一线员工就像军队的冲锋陷阵的战士,偶尔攻坚一下可以,但是长年累月吃不好、穿不暖、睡不饱,关键时刻怎么打硬仗

稍微解释一下字面意思中的歪理:工作不像开火车,日复一日年复一年地以同一个频率“况且况且”地进行下去,而是有各种轻重缓急的任务密集交错。

假设一下,如果每天加班到晚上12点,并且正在处理很重要的任务,如果这时候插入一项紧急任务,怎么处理?要么每天再加班3个小时,两不耽误,这样牛都要累死;要么放下重要任务不做,先处理紧急任务,这个方法做下去很快没被处理的重要任务就会变成下个周期的重要且紧急任务,造成恶性循环。

我们经常可以看到这个奇怪的观点却不以为然:这件事情很紧急,先把手头事情放到下周。敢情下周就没有重要工作了?或者下周重要工作顺延?如果能随意顺延重要工作的话,那我们为目标制定的计划如何执行?“今日事,今日毕”是执行力的最基本要求。

如果每天8小时就能完成既定工作的话,那么临时插入紧急任务时就可以有充足的时间用来加班,两不耽误。

到头来还是要加班?接着就要说我另一个看法了:“如果有一项重要又紧急的任务,那就交个最忙的那个人吧

这又是一个奇怪的观点,依旧很古怪,依旧漏洞百出。其实解释起来很简单:如果一个人工作比别人更忙,依旧能做得很好的话,说明这个人善于管理自己时间、解决问题有自己独到的方法,把一项紧急又重要的工作交给他比交给一个相对比较闲的人风险反而更小。

这就解决了上面加班的问题,做个最忙的人,争取8小时内解决战斗,即使中途插入紧急任务。当然,这也只是我的目标,要做到这一点,还需要继续努力。

目前主要手段还是有一些的

  1. 学习并做好目标管理、定期回顾更新,这很重要,忙碌的工作总会让我们忘了当初划定的方向、目标,没有人愿意回头看到自己工作不少但成果几乎没有

  2. 制定好长期、中期、短期计划,中短期包括:季度、月、周、日。并善用合适工具去管理这些计划,时刻能看到今天、本周,以及下一周期的计划。

  3. 学习、再学习、努力学习。如果一个月后没有看到明显的成长那就再使使劲,如果一个季度后还没看到成长就该反思了。

最后一句话用来给自己反思:如果十年如一日的工作内容、效率,那么生活的意义在哪里?

加班干什么

如果真要加班的话,那加班干什么?答案是学习。经常看到长者对年轻人的劝诫,趁年轻要努力。但这努力很容易就被转化成在公司加班了。

如果把生活的时间划分一下的话,我倾向于:8小时工作、8小时睡觉、8小时其他(学习、娱乐……),别忘了,周末有两个整天可以利用!!!我们从来就不缺乏时间,缺乏的是如何高效地利用时间

工欲善其事,必先利其器。时间再怎么缺乏,也要挤点出来学习如何管理时间;工作再怎么忙碌,也要“闲”下来,让自己学会更高效地工作。

工作中确实能积累到很多经验,学习到很多知识。但是系统化学习永远都是必不可少的,尤其是一些知识型岗位,比如码农。

加班的地点

既然加班内容主要是学习,那地点最好是一个安静不受打扰的地方。对我来说要求更低,只好不是背诵这种需要高度集中注意力、丝毫不能被打扰,需要绝对的安静。其他技术类书籍我可以在任何场合下看,例如公交、地铁、火车。前提是,一段不被人打断的时间。

因此,咖啡厅是个很好的地方,不用去洗衣服、做饭、烧开水、整理房间,因为你想做也做不了。如果中午能凑合一下星巴克的简餐,就有足足一整天的时间去看书了。当然,得是周末。工作日的话,晚上去公司的休闲吧,回家有书房最好了。所以每天早上出门前我都会尽量收拾好房间,这样回到家后一推开门就会有个好心情,开始一整晚的“旅程”。以前在北京时,有很长一段时间,每天公交车上下班加起来2小时,那个期间看过的书太多了。也是在那之后养成了一个习惯:出门时在随身背包里放本书,等人、等菜、等车时都可以随时拿出来看。

总结

  • 加班于私于公都不是好现象,于己不利于成长,当然白天的工作内容就是“学习xxx”的例外;于公,工作效率、战斗力都有疑问,工作能力十年如一日的员工应该不是公司想看到的

  • 不加班不等同于像公务员那样,看看报纸、喝喝茶,到点就甩手回家。而是应该不断学习与成长,放弃心理舒适区,大胆走出来,风景更美好。对于环境,要么享受,要么离开。没有所谓的赖在那里,还一天一个不喜欢(不喜欢现在的工作方式、编程语言),或者喜欢(虽然这种工作/做事方式效率低,但是我喜欢,不想改变)

  • 不是每个成长都值得庆幸,古有“逆水行舟,不进则退”。今天有“长江后浪拍前浪,前浪死在沙滩上”,步伐稍微慢点就会被后浪拍在沙滩上,而且无法回头

  • 没有完美的环境,不抱怨,马上行动。只要用心,解决办法总归是有的

分类: Lifestyles 标签:

Safari 5.1不再支持本地PAC文件

2011年12月30日 没有评论

自把MacOS从SL升级到Lion后,Safari就不能使用pac文件了。

查了相关资料后发现原因是:Safari 5.1中修改沙箱环境的机制本地pac文件做代理已经不支持了,使用远程的就可以。例如http://开头的。

修改前:file://…,在Safari 5.1中已经失效

修改后:http://losthit.com/f/sshd.pac,可用。

该pac文件来自autoproxy,考虑到autoproxy使用的GAE有时会超过配额,或者撞墙导致无法使用。所以下载了一份自己保存,稍后做个脚本自动更新,当然还得加上校验。

参考链接:https://discussions.apple.com/message/15731770#15731770

分类: Computer Science, MacOS, 软件 标签: , ,

如何创建动态MOTD

2011年9月10日 没有评论

背景介绍

刚到淘宝时发现很多服务器登陆后都会显示一段AsciiArt的信息,觉得很好玩,也稍微有点用。如果你关心具体是什么,可以发送简历到jinxi.kj@taobao.com:)

如何显示静态MOTD

以上是背景,上网搜了一下,找到了相关的资料。其实很简单,只要修改了/etc/motd文件,登陆时就会被显示出来。如果需要增加颜色的话,可以参照这里的方法:“So You Like Color–The Mysterious ^[[ Characters" (http://www.linuxjournal.com/article/8603)。在vim中输入Ctrl+V后再按ESC,接下来写上颜色代码就行。有玩过term bbs的话应该会很熟悉。

如何显示动态MOTD

设置好/etc/motd后,马上就发现了一个问题,这是个静态的内容,自然就不能显示动态的信息。比如ip地址、硬盘占用、进程数等,除此之外,也没人喜欢部署多台机器时手动在motd中设置机器相关的参数,比如CPU、core数等。于是我就找到了这篇Blog: "HOWTO: Creating a Dynamic MOTD in Linux" (http://parkersamp.com/2010/10/howto-creating-a-dynamic-motd-in-linux/)。

具体方法很简单,编写一个脚本显示动态的motd,然后添加到/etc/profile中执行就行了。当然还需要禁用/etc/motd的显示。

如何禁用静态MOTD

修改: /etc/ssh/sshd_config
PrintMotd no
然后重启sshd: /etc/init.d/sshd restart or service sshd restart
更多信息参考上面提到的Blog。当然,最简单最暴力的方法是把/etc/motd文件中内容清空。

如何安装动态MOTD脚本

1. 将动态MOTD脚本放到某个目录下,比如/usr/local/bin/dynmotd。
2. 将脚本添加到/etc/profile中
修改: /etc/profile
/usr/local/bin/dynmotd

我自定义的Python脚本

由于前面我找到的Blog中使用的脚本是shell导致不方便修改,而且部分信息还是写死的;另一方面,Mac下面不能完全兼容。所以我自己用Python实现了一个类似的脚本,支持MacOS与Linux。考虑到不想把这个简单脚本搞得太复杂,所以没有用到兼容性、全面性更好地psutil。有兴趣的可以自己试试。

脚本可以到这里获取: https://github.com/chzealot/tools/tree/master/python/dynmotd

显示效果

MacOS(Darwin)下的显示效果

MacOS(Darwin)下的显示效果

Linux下的显示效果

Linux下的显示效果

这样理解演讲如何?

2011年9月2日 1 条评论

一、概述
二、什么是演讲

  1. 目的
  2. 过程
  3. 演讲者的准备
  4. Slides的作用
  5. 听众的要求
  6. 强调:信息流动的必然方向
  7. 示例:直观化的slide:表 vs 图 vs 精简后的图

三、最后的吐槽

一、概述

虽然不多,但是我一直以来还是比较关注演讲的技巧,毕竟这不是个人英雄时代。我们总是一个群体在协作,而通过高质量演讲的方式去交流,必然会提高协作的效率,发挥出1+1远远大于1的效果。

特别说明一下,这是我突然的一个想法,记录于此。不要理解成奇技淫巧,更不要理解成说教。

二、什么是演讲

1. 目的
在公司内部,演讲的目的更加倾向于信息、知识的交流与传播。而演讲的技巧无非是让交流的双方能有更大的收获,让传播的过程更加高效。

2. 过程
这是我个人的理解(我能想到的,使用电脑做图,最快速方法就是这个了)

演讲的结构演讲的结构

演讲的结构

注:请原谅我的字迹 & 点击图片查看大图。
演讲的过程就是,演讲者将信息(或知识,本文不同地方会混用两个概念,该细节与本文无关)通过一定方法,传递给听众,并企图让听众有同样认识。注意,是企图哦。不同人的知识结构、思维方式都是不同的,而且传播的过程中非常容易出现信息丢失,听众获取到的信息与演讲者的理解自然是有差异的。
更详细地说,是演讲者将信息结构抽取出来,并以更加抽象、形式化的方式展现给听众,通过介绍、讲解等方式分享给听众。听众通过自己的理解,初步笔记,辅以必要的回顾学习,从而形成自己的理解。
整个过程就像以前高中老师描述读书一样:读书首先是将书越读越薄,然后越读越厚。读薄的过程是快速摸清知识的体系结构,了然于胸,自然变薄了。读厚的过程是在了解只是体系结构后,增加精读,以及自己的理解,自然就把书读厚了。相当于,先有骨架,后有血肉,自然把书读活了。

永远不涉及不必要的细节,永远将关注点放到High Level的层面上。A工具比B工具好,只要介绍特点、差异等重要信息就行,没必要把怎么下载,怎么安装,使用方法,等等等等,挨个给听众讲一遍!

3. 演讲者的准备
首先强调一点,具体场景不一样,方式也不一样,准备工作的时间、详细程度、方式也必然有差异。
常规来说,可以将知识的结构剥离出来,然后抽象成易于理解的形式。两个步骤都非常重要。第一步,剥离出信息的结构,就可以清晰地摸清复杂问题的本质,把复杂问题简单化。第二步,是将信息转换成易于理解的形式,不能被人理解的知识,再好也白搭。

4. Slides的作用
Slide最大的好处之一是它不是文档,尽管存在少部分人喜欢把ppt做成方便全屏翻页的word文档。按照我的理解,信息传递过程中的形式依次是1)文档 2)纲要 3) 高度抽象化的slide 4)笔记纲要 5)文档
当演讲者准备一份1万字的“文档”(抽象的文档,也可以是仅存于脑子里面的东西)来讲解复杂的知识时,那么观众需要依次在脑子中完成2)3)两个步骤,即在右脑中快速形成一个错误百出、信息损耗及其严重的摘要和抽象的认识,并记录下来,形成一个自己的、模糊的、甚至是大量错误的知识(抽象的文档)。
按照我的理解,演讲者的准备层级(即文档=>纲要=>抽象化的slide)越高,信息损耗越低,观众理解越快速越准确。

5. 听众的要求
一个好的听众,自然不能空手而来,默默地听完后,拍拍屁股走人。对于复杂的,或者之前完全没有认识的信息,首先要做好功课,不妨提前要到演讲者的slide。听的过程中,及时记录笔记。至于笔记的形式和方法,康奈尔笔记法(http://www.mifengtd.cn/articles/cornell-notebook-intro-and-ad.html)值得推荐。而听众脑海中的“文档”,一部分是演讲者通过讲动听的故事留下来的,另一部分是听众结合之前的笔记形成自己的理解和认识。

6. 强调:信息流动的必然方向
按照上面图中,我的理解是信息自左向右流动,每个步骤缺一不可,也不会缺少。当演讲者没有准备纲要或者高度抽象易于理解的slide时,这部分就会在听众右脑自动生成,至于正确性、完整性,就无法保证了。

7. 示例:直观化的slide:表 vs 图 vs 精简后的图
slide应当最大程度地提供高度抽象化的信息,以更加直观的形式展现,从而被听众高效的右脑直接接受。而不是绕到用于逻辑、文字处理的且低效的左脑去工作。
这里有个示例

采用更直观的表达

采用更直观的表达

点击图片查看大图
通过将表格逐步抽象化成更加直观的图,减少噪音,从而也减少了误解。

三、最后的吐槽

最后,忍不住吐槽一下:真的只能、必须、不可避免地要把听众讲得异常迷糊吗?!
在过去的时间里,应该也包括更长的将来时间里,我都不断地听到这个声音

  • “我的主题本来就很复杂,所以讲出来的内容当然很复杂呀”
  • “这么复杂的东西,能让观众听懂1/3就不错了”
  • “反正讲完后还得花老长时间去学习,所以听不懂也没关系啊”

对此,我表示很奇怪。这是为什么呢?

分类: GTD, 演讲 标签:

Mongodb Beijing Conference 2011

2011年3月7日 2 条评论

上周四10gen在北京举办了Mongodb Beijing 2011,这半年里我也一直在生产环境使用Mongodb,对此还是很有兴趣的。特地过去听了几场收获还挺大的,在Blog里分享,也算是记录一下。

特别注明一下,我虽然一直在用Mongodb,但是仅关注其性能、方便,最重要的是方便地对单个document进行原子的findAndModify操作,反而对稳定性要求非常低,低到数据都不用备份的程度。因此,对于Mongodb的了解程度在会场人群中应该不算很高。

会议安排:上午先后有两场10gen工程师Roger和Alvin的演讲,下午分别是国内四位工程师分两个会场同时讲四个主题。

上午两场比较像Live Tutorial,对于我这种没有系统研究过的人来说还是蛮实用的。

第一场是Roger同学的Intro & Schema Design,从数据建模引入,重点还是在于通过Blog的案例,针对Document-Based数据库Schema Design,对比传统的关系型数据库,进行详细的分析,纯属教学性质的分享。特别说明的是,刚下载slides后发现有两个backup分别是DBRef和BSON,貌似大家都熟悉了,Q&A环节中没有用到。

第二场Alvin同学分享的是Replication and Sharding,同样是Tutorial性质的介绍。不过,对相应的机制及很可能遇到的隐患做了系统的说明,不得不说在讲解Replication Sets和Sharding机制时Slide动画做得干净、明了,貌似这点国人很少有兴趣去折腾。

总之,以上两场算是Mongodb官方分享,都只是系统性地做入门介绍。关于Replication Sets中Primary Member失效时Time Windows内仍然会有数据丢失风险,Alvin解释是需要getLastError,在应用层做处理;同样,Auto-Sharding也没有像官网提到的”without compromising functionality”。难怪有人评论没有说服力。

下午,分了两个会场同时进行,我选择了Yottaa那个实践分享的会场。这是一家刚成立一样的Startup,使用的技术和工具都比较新,这点很有意思。关于Mongodb的使用除了看Slide其他的也没什么好说的。在看到500G的数据,机器8G Memory时我就好奇问了一下性能问题,答案是Yottaa不太关心数据实时性。提问时有个插曲,我提到了500G数据文件load到内存时,大家都笑了,但是这不是我的问题,会后在微博我也解释了,Mongodb这类NoSQL基本还是将内存管理工作交给OS处理,所谓的LRU算法只不过是OS处理虚拟内存是常见的一种方法而已。数据文件全部load到内存的说法没啥错误,这点官网也有明确的解释:Mongodb.org: Caching – Memory Mapped Storage Engine

关于我提的数据量问题,会后在微博上也有童鞋很Nice地继续解释了一下:新浪微博评论。对于数据实时性以前可能我还不在乎,但是经历酒店价格数据实时处理后(包括搜索结果页的实时性),对这个还是比较谨慎的:1) 4sq宕机教训证明了虚拟内存性能值得担忧;2) 自身教训来说数据实时性要求不高的结论慎重点比较好。3) 突然需要调整为实时响应最新的数据的话,改动还蛮大,特别是针对我们这种搜索引擎来说,相信看过twitter实时搜索技术介绍大概能了解。

由于临时有事回公司了,没看最后一场。唯一遗憾的是没有GridFS和Map/Reduce的专门介绍。

当条件不成立时,命题永真

2011年3月7日 没有评论

在数理逻辑课入门时老师就会讲到这个命题:P->Q,当条件P=False时,不论Q为True or False,命题永真(注意是命题永真,不是结论永真)[注:见Wikipedia: 真值表]。

很遗憾的是这门课程不是大家都学,也不是所有人都学会了,所以经常看到一下违背这个逻辑的事情。比如,仅仅只是假设,你的KPI(Key Performance Indicators,关键业绩指标)中有没有这样一条:当同事A与B打架时,你做了事情X可以得到基本分,做了事情Y可以得到超出期望分。其实按照特定企业文化、团队目标设定某些特定的KPI(再强调一下前面打架的例子仅仅是假设,实际上应该没有这么荒唐的指标吧)都很正常,关键在于假设不成立时,该项得分给了满分还是零分,或者提前调整该项指标。按照真值表,条件(即打架事件)不成立时,结论(即你采取的行动)不论如何,命题永真,该项得分应为满分,但实际操作时往往是0分,杯具了吧。

以上仅是引子,我想说的是,合理地制定以结果为导向KPI真的很重要。上面的例子中很显然非常消极被动,面对一个指标,只能有心无力,感兴趣的事情做好了反而没人关注。

以结果为导向主要原因有三方面。

  • 首先,结果导向能更有效的提高工程师的主动性,虽然也有其他方法去促使积极主动,但是绩效考核中的结果导向能起到一个很大的正向推动作用;

  • 其次,在一个年轻的工程师团队中,考核中结果导向的指标与团队的指标直接或间接关联,能使得团队成员,尤其是工程师,有更大的成就感;

  • 最后,通过结果导向的KPI,在提高积极性的同时,能让工程师更快的成长,不至于每个季度下来零碎的过程性指标完成不少,但是难有很好的成长。

目前,有些工程师,尤其是前端工程师可能更多地是被动响应产品经理大量零碎的需求,这样很难制定结果导向的绩效指标。

如果加重结果导向的绩效指标也是可行的。

  • 首先,产品经理将更多的精力用于用户行为分析等,并制定出高阶的产品改进需求。细化的需求主要由工程师提出,使得被动响应变成主动积极。这一点在Facebook用得比较极致,甚至产品经理提出的需求如果不能打动工程师,那么就很可能不会被采纳;

  • 其次,很多时候细化的产品需求背后涉及了大量的技术点,由工程师来细化需求,在产品改进与技术成本及代价上做出较好的平衡,尤其是展现层面的改进,前端工程师对页面元素、交互方式有更全面、深刻的认识。例如,产品经理在分析用户,研究产品后得出一个通过图片展现降低跳出率的想法,转交给工程师后,由工程师通过白板给出UI原型图并解释交互方式。这时,工程师可以根据自己的特长给出一个技术复杂(可能)但是效果很好的方案,反而由产品经理提出细化的方案的话要么很粗糙,要么实现起来极其复杂。需要强调的是,细化需求如果由产品经理提出,不管事后通过多么好的沟通、讨论过程,终究不如先由工程师分析的效果好,因为细化的过程可能涉及到架构层面,甚至项目风险等问题;

  • 第三,工程师不应当仅关注技术点,反而应当拿出一定的精力去理解产品,理解用户需求,以求得在小团队中充分发挥出每一个人的最大作用。我们已经被学上了十几年,好不容易从学校熬出来了,就不要再被工作给上了;不能像学校那样总感觉做的、学的没啥用。在一个商业公司,永远都是先有用户然后有产品最后有技术,不能最大化的服务于产品的技术都是扯淡。

面向结果的方式明显有很多好处:通过制定若干长期的目标,使得我们从每周,甚至每天,这种细分粒度的固定办公时间中解脱出来;员工成就感更高、成长更快;流失率更低;更强调结果,前提是个人目标应对应于团队的目标。

相比以上积极面来说,花些精力去克服这些负面影响还是值得的:难免有些工作很难做准确的效果评估;管理难度更大;有可能出现员工之间的竞争,如果没处理好的话,等等。

* 参考:Wikipedia: ROWE – Results Only Work Environment



注:审阅时看到“扯淡”两字觉得都不像是我写的,其实大多时候我都是可以通融和变通的,但不想再改动了,只是补充一点:以上看法只是我觉得可行,行得通,必要时可以甚至必须要变通,所以现实中与以上相反的观点很多时候我也是认同的。部分例子对观点仅作解释,不起到论证作用。

Gmail特色以及使用方法

2011年2月26日 没有评论

Gmail特色以及使用方法
1. Labels, filters, and stars
a) Labels相当于邮件分类
b) Filter相当于outlook的邮件规则
比如说可以自动把监控系统发出来的邮件移到某个特定的label里面
创建Filter示例,打开邮件后,点击左上角的倒三角,就可以设置该类邮件的过滤器

c) stars是标星的邮件
特别重要的邮件可以标星,方便以后继续查看。比如说,有人分享了一篇很长的文章,可以先标星(快捷键s),然后存档(快捷键e)。
以后需要继续查看的话,可以在左侧label列表中找stars标签,或者用快捷键组合gs。
2. 会话线索化
Gmail中会自动把同一个会话中的所有邮件都组织在一起,保持邮件连贯性

3. IMAP(Internet Message Access Protocol)
邮件协议最常见的有POP和IMAP,Gmail中都支持。POP协议最大缺点就是单向传输,如果每天都有上百封邮件要处理,那么,在多台电脑上处理邮件将会极其困难。因为,在一台电脑上处理邮件的状态无法和另一台电脑同步。从而导致同一封邮件看了一遍又一遍。
IMAP最大的两个特色及设置方法如下(前提是使用支持IMAP的客户端)
a) 邮件分类同步
客户端可以获取服务器上的邮件分类。重装电脑,换台机器,不用导入任何文件,就可以获取到以前设置的邮件分类(Labels)
b) 邮件状态同步
手机上看完邮件后,该邮件状态变成已经阅读,且该状态会被更新到服务器。换到电脑上查看邮件时,该邮件状态已经是阅读过的状态了。不至于手机上看完了,电脑上还是未阅读的新邮件。
邮件一旦被操作就会在所有客户端同步。比如存档,那么其他客户端的收件箱里都不会有该邮件了。
c) 设置IMAP访问
Outlook就支持IMAP访问,设置方法在Google Help中已经有了,这一篇是Outlook 2007中的设置方法

https://mail.google.com/support/bin/answer.py?hl=en&answer=77689

4. 手机访问

http://m.google.com,你懂的。

示例:ipod touch中设置如下

邮箱显示如下

5. Chat:text, voice, video
直接在浏览器里登录gmail,就可以聊天。而且,gmail是世界上第一个把网页版聊天做得比pc客户端 上还要强大工具。比如说浏览器中的视频聊天,这个在Google talk中是不支持的。
6. 插件
a) 插件在实验室中,查看方法settings->Labs
在这里可以启用或禁用插件
b) Custom keyboard shortcuts
设置快捷键,方便邮件操作,设置截图

记不住快捷键怎么办?按问号“?”(处于文本编辑状态时,需要先按一下Esc)。
7. 文件拖拽
最新的HTML5协议中已经支持文件直接拖拽到网页中,gmail和chrome都已经支持html5(最新的IE和Firefox应该也支持了)。
以后添加附件到邮箱中只需要拖拽即可,见下图,cool~

注:

前一篇日志把页面结构弄乱了,先顶下去,稍候上图

分类: Google 标签:

海盗分金问题分析与解决

2010年8月2日 1 条评论

海盗分金问题分析与解决

——Nim取子问题变形后的解决方案

全文下载链接:海盗分金问题分析与解决.pdf

Author: Zealot Ke(kejie[at]kuxun.cn)
Date: 2010/7/30

背景

强哥邮件发出一个题目

  1. 有5个海盗,特别的残忍,特别的聪明
  2. 他们抢了100个金币,要进行分配,每个人都想分配足够多的金币,他们寸步不让.分配顺序是:5号海盗->4号海盗…1号海盗,即是:先由5号海盗决定如何分配,若分配不均,5号被扔下海,4号海盗再决定如何分配,依次类推.
  3. 如果没有二分之一或以上的海盗同意,分配人将被其他人扔下大海.
  4. 假如你是5号海盗,你会如何分配金币.确保自己不会被扔下大海,而且让其他4个海盗心服口服.

定义问题

5号海盗必须按照上述规则,找出最优分配方案,否则将被其他人扔下大海。

当前状态

正确分配方案还没出来,必须尽快找出最优解。

分析

典型的nim取子问题的变形,采用倒推方式即可找到最优解。

制定解决方案

倒推方法如下所示

  1. 如果只有一个海盗,如何分配?
  2. 如果有两个海盗,如何分配?
  3. 如果有n个海盗,每个海盗至少需要几个人同意?找出n-1个海盗情况下的分配方案中,需要收买多少海盗?最低需要多少金币?

实现解决方案

倒推方法实现如下表所示,每一行表示一种人数情况下的分配方案,也即,最后一行给出5号海盗的分配方案。

分配方案倒推分析表

分配方案倒推分析表

注意:从表中可以看出聪明是大前提,当然残忍也是。nim取子游戏向来是君子游戏,没有这个前提的话,后面的海盗不按套路出牌就不可能有最优解。

标准化解决方案

从上表不难看出规律,也即,自己拿尽可能多的金币,同时保证后面的人依次分配0、1交错的金币数。规范化命题如下
*命题: 假设对于n个聪明、残忍的海盗(n≥1),抢了Gold个金币,要进行分配,每个人都想分配足够多的金币,他们寸步不让。分配顺序是:n号海盗->n-1号海盗…1号海盗,即是:先由n号海盗决定如何分配,若分配不均,n号被扔下海,n-1号海盗再决定如何分配,依次类推。在该规则下,n号海盗最佳分配方案应当如此(为简单,避免使用地板函数,按n为奇偶数分类讨论):
不妨假设ones为得到1个金币海盗数,zeros为得到0个金币的海盗数。

  1. 当n为奇数时,ones=zeros=(n-1)/2,分配方案为Gold-ones,0,1…0,1
  2. 当n为偶数时,ones=( n-2)/2,zeros=n/2,分配方案为Gold-ones,0,1…1,0

该命题从上述分析中的规律中得出,不是定理,更不是公理,作为标准化解决方案需要严格证明。

证明:
注释:使用跳跃数学归纳法证明,跳跃的step为2。
先证明n为奇数时命题是否成立。
当n=1时,显然该命题成立
假设当n=m(m>1)时命题成立,则分配方案为
Ones(m) = Zeros(m) = (m-1)/2
Proposal(m) = Gold-Ones(m),0,1,…,0,1
= Gold-(m-1)/2, 0, 1, …,0,1
当n=m+1时,显然命题成立,理由如下
Ones(m+1) = (m+1-2)/2=(m-1)/2,Zeros(m+1) = (m+1)/2
注意:a) m+1为偶数,计算ones和zeros需要换个公式b) 对比n=m情形,仅仅是多了个0。
Proposal(m+1) = Gold-Ones(m+1),0,1,…,0,1,0
= Gold-(m-1)/2, 0, 1, …,0,1,0
对比Ones(m),Ones(m+1),Zeros(m),Zeros(m+1)可以看出仅仅是在Proposal(m)序列后面添个0。这会导致Proposal(m+1)与Proposal(m)两个序列中,0、1交错序列刚好错位,对应金币分配方案中则为:m+1号海盗分配方案就是把Proposal(m)中没有得到金币的人每人给1个金币实现自己金币最大化,同时保证同意的人数大于等于2。
综上所述,当n为奇数时,该命题成立。
再证明n为偶数时命题是否成立。
当n=2时,命题成立(大于的最小偶数只能是2)
归纳方法同1。
综合1、2分析,该命题成立。
证毕。

该标准化解决方案用程序实现如下
说明:该程序考虑了金币数量远小于海盗数量时,最先出来分配的部分海盗都得喂鲨鱼去了。

$ cat nim.c
#include 

const int g_first = 2;
const int g_zero = 0;
const int g_one = 1;

int print_proposal(int *gold, int *pirate, int *ones, int *zeros, int *status) {
        int             ret = 1;
        int             number = 0;
        int             remain = *gold - *ones;
        if (*pirate <= 0) {
                printf(".\n");
                return 0;
        }
        if (remain <= 0) {
                number = 0;     /* not enough gold, killed by others, regenerate proposal */
                ret = 1;        /* conitnue */

                /* regenerate proposal */
                if (*pirate % 2 == 0) {
                        *ones = (*pirate - 2) / 2;
                        *zeros = *pirate / 2;
                } else {
                        *ones = *zeros = (*pirate - 1) / 2;
                }
        } else if (*status == g_one) {
                number = 1;
                *ones--;
                *status = g_zero;
        } else if (*status == g_zero) {
                number = 0;
                *zeros--;
                *status = g_one;
        } else {
                number = remain;
                *status = g_zero;
        }
        if (*status != g_first && *ones <= 0 && *zeros <= 0) {
                ret = 0;
        }

        printf("%d ", number);
        *pirate = *pirate - 1;

        return ret;
}

int main()
{
        int             gold;
        int             pirate;
        int             ones;
        int             zeros;
        int             temp;
        int             status;         /* process first, zero or one */
        printf("Please Enter gold and pirate number:\n");
        while (scanf("%d %d", &gold, &pirate) == 2) {
                if (pirate < 1 || gold < 1)
                        break;

                if (pirate % 2 == 0) {
                        ones = (pirate - 2) / 2;
                        zeros = pirate / 2;
                } else {
                        ones = zeros = (pirate - 1) / 2;
                }

                status = g_first;
                printf("Proposal(%d, %d) is: ", gold, pirate);
                temp = pirate;
                while (print_proposal(&gold, &temp, &ones, &zeros, &status))
                        ;
                if (pirate == 1)
                        printf(".\n");

                printf("\n");
                printf("Please Enter gold and pirate number:\n");
        }
        return 0;
}

程序运行结果如下所示

$ gcc nim.c -o nim
$ ./nim
Please Enter gold and pirate number:
100 1
Proposal(100, 1) is: 100 .

Please Enter gold and pirate number:
100 2
Proposal(100, 2) is: 100 0 .

Please Enter gold and pirate number:
100 3
Proposal(100, 3) is: 99 0 1 .

Please Enter gold and pirate number:
100 4
Proposal(100, 4) is: 99 0 1 0 .

Please Enter gold and pirate number:
100 5
Proposal(100, 5) is: 98 0 1 0 1 .

Please Enter gold and pirate number:
0

决定下一步

本问题到此为止,暂时没有下一步动作。

总结

这个结论告诉我们

  1. 最先掌握分配权的人,看似最危险,胆小的人可能会担心所有人都不支持你,你就只能下海去喂鲨鱼了。其实,他优先掌握了主动权,天下武功,唯快不破,掌握市场先机很重要。
  2. 越快越好,但不能快过了头。100个金币,1000个海盗的话,最先出来分配的人必然死掉。同样的,20年前搞酒店搜索,率先占据主动权,快得一塌糊涂那也没戏。

完。

粗略读完《深入理解计算机系统》

2010年7月13日 没有评论

书名:深入理解计算机系统(修订版)
英文名:Computer Systems A Programmer’s Perspective (简称CSAPP)
从英文名称就可以看出这是一本面向程序员的书籍。豆瓣上的链接:http://book.douban.com/subject/1230413/

这本书讲述的内容就像名称里说的那样,从程序员观点来研究和发掘计算机系统的架构和潜力,包括信息计算的基础理论,也包括大量硬件、体系结构、操作系统层的知识,并结合编程开发提供了相应的参考信息。是一本难得的好书。

从写作上来讲,这本书也非常不错。全书自底向上,从信息理论入手,逐步扩展到硬件、汇编、操作系统,网络编程,最后到应用软件层(以http server为例分析并发编程)。而开篇第一章就把整本书的脉络概括了,后面每一章都只不过是第一章每一小节的细化。因此,阅读起来全局把握上很轻松,而这也恰恰是非常关键的一点。

整本书非常厚,800多页,大而全,但终究是一本系统级的书,更深入的细节还是只有比较概念性的介绍。比如汇编程序,虚拟存储器管理,基于事件触发的并发网络编程等等。本书每一章都可以独立成书,深入分析。实际上,我们的大学四年中的教材基本上就是这样独立编排的。所以这本书可以算是一个系统性的参考,用于辅助在头脑中建立整机的意识。具体到某一个特定的领域,需要找更详细的资料阅读才能有更好的理解。

最后,书中的习题看上去非常不错,而且都有细致的答案供参考。受限于公交上阅读环境,没有仔细看这部分。以后可以研究研究。

不过限于书中知识点大而全,对cs专业的学生来说,更好的选择是大一买下来显摆,大二消遣,大三把玩,大四送给小师妹。不是这本书不够深入,只是我觉得相比四年的课程来讲,这本书中的内容在cs毕业生眼里是必须精通的,没必要放到毕业后再继续学习这些基础。现在看看这本书,我也只能后悔没早点买到。

哦,对了,书中开篇介绍了一些非常有意思的实验题,比正文有趣多了。

R61在linux/debian下安装madwifi无线驱动

2010年4月6日 没有评论

本文记录Thinkpad R61i在debian lenny下安装madwifi驱动程序,替代ath5k,实现无线上网。
主要参考:http://forum.ubuntu.org.cn/viewtopic.php?f=116&t=169205。
仅作为tp安装linux的备忘,欢迎评论。

1. 下载
   Download the latest madwifi snapshot. // Google it

2. 解压
   $ tar zxvf madwifi-hal-0.10.5.6-current.tar.gz

3. 编译安装madwifi // 首先通过apt安装编译环境
   $ sudo aptitude install build-essential linux-headers-$(uname -r)
   $ make
   $ sudo make install

4. 安装module
   $ sudo modprobe ath_pci

5. 使网卡每次开机时都加载, make it load every time you boot
   $ sudo vi /etc/modules
   添加一行,如下
     ath_pci

6. 重新启动机器
   $ sudo reboot

注释 && 备忘
1. 为保证生效,重启前确认已屏蔽ath5k(默认驱动程序有可能是这个)
   检查是否已安装ath5k
   $ lsmod |grep ath5k
   有,则添加到blacklist
   $ cat /etc/modprobe.d/blacklist.conf
     blacklist ath5k
2. 确认安装驱动是否成功
   $ lsmod | grep ath_pci
     ath_pci               201176  0
     wlan                  193392  5 wlan_wep,wlan_scan_sta,ath_rate_sample,ath_pci
     ath_hal               300768  3 ath_rate_sample,ath_pci
3. 硬件型号查看
   $ lspci |grep Ethernet
     00:19.0 Ethernet controller: Intel Corporation 82566MM Gigabit Network Connection (rev 03)
     03:00.0 Ethernet controller: Atheros Communications Inc. AR242x 802.11abg Wireless PCI Express Adapter (rev 01)
4. ath5k是madwifi替代品,除非ath5k下无法连接无线,不建议使用madwifi