代码之丑(十三)

第一次见到这样的代码时,我的第一感觉是,它真复杂:  List<Map<String, String>> configurations;

可只要理性稍一回归,便不难察觉,它少东西了。少什么了呢?

看看这段代码如何使用,下面是一个缩略的版本:

for (Map<String, String> configuration : configurations) {  for (Map.Entry<String, String> entry : configuration.entrySet()) {    System.out.println(entry.getKey() + " " + entry.getValue());  }}

说白了很简单,其实就是要拿到存在Map里的键值对。在面向对象的程序语言中,有一种神奇的构造,叫做类,而它有一个很重要的特点叫做封装。是的,这段代码少了类,少了封装。闲言少叙,封装起来:

public class ConfigurationItem {  private String name;  private String value;  …}

于是,那个容器嵌套容器的声明变成了  List<ConfigurationItem> configurations;

有了类,有了封装,我们就可以再进一步进行封装,比如前面那段代码里的  entry.getKey() + " " + entry.getValue()

实际上,可能只是为了得到这一项的字符串表示而已,那就不如直接提供一个方法:

public class ConfigurationItem {  […]

代码之丑(十二)

诸位Java程序员,想必大家对SimpleDateFormat并不陌生。不过,你是否知道,SimpleDateFormat不是线程安全的(thread safe)。这意味着,下面的代码是错误的:

class Sample {  private static final DateFormat format = new SimpleDateFormat("yyyy.MM.dd");

  public String getCurrentDateText() {    return format.format(new Date());  }}

从功能的角度上看,单独执行这段代码是没有问题的,但放到多线程环境下,因为SimpleDateFormat不是线程安全的,这段代码就会出错。所以,要想让这段代码正确,我们只要稍做微调:

public class Sample {    public String getCurrentDateText() {        return new SimpleDateFormat("yyyy.MM.dd").format(new Date());    }}

不知你是否注意到,这里的调整只是由原来的共享format这个变量,变成了每次调用这个方法时创建出一个新的SimpleDateFormat变量。

作为一个专业程序员,我们当然知道,相比于共享一个变量的开销要比每次创建小。之所以我们必须这么做,是因为SimpleDateFormat不是线程安全的。但从SimpleDateFormat提供给我们的接口上来看,实在让人看不出它与线程安全有和相干。那接下来,我们就要打开JDK的源码,看一下其中的代码之丑。

如果你手头没有JDK的源码,这里是个不错的参考。

在format方法里,有这样一段代码:  calendar.setTime(date);

其中,calendar是DateFormat的protected字段。这条语句改变了calendar,稍后,calendar还会用到(在subFormat方法里),而这就是引发问题的根源。

想象一下,在一个多线程环境下,有两个线程持有了同一个SimpleDateFormat的实例,分别调用format方法:

线程1调用format方法,改变了calendar这个字段。 中断来了。 线程2开始执行,它也改变了calendar。 又中断了。 线程1回来了,此时,calendar已然不是它所设的值,而是走上了线程2设计的道路。 BANG!!! […]

代码之丑(十一)

全局变量永远是不受欢迎的,因为它会带来太多的问题,所以,诸如Java这样的程序设计语言干脆摒弃了全局变量。一旦我们有机会面对全局变量,想都不要想,干掉它。

if (IDLE == g_status) {  …}

那个g打头的家伙就是全局变量,它就是我们的靶子。第一直觉,我们不要直接访问全局变量,那就用函数把它封装起来:

int getCurrentStatus() {  return gStatus;}

于是,代码变身了:

if (getCurrentStatus() == IDLE) {  …}

把变量封装成函数,从某种角度说,这是一种进步。但我想说,这还不够。这只是一种简单的封装,本质上来说,这与直接暴露数据差别不大,我们需要更好的封装,通常的做法是封装出行为。行为从哪来,从实际需求来。

就以上面这段代码为例,我们封装了status,其实,它的目的是为了与IDLE状态相比较,这就是一种行为,我们可以这样封装:

bool isCurrentStatus(int status) {  return status == g_status;}

if (isCurrentStatus(IDLE)) {  …}

还有一种修改方式,既然IDLE是一个固定的常量,索性把它也隐藏起来:

bool isIdle() {  return IDLE == g_status;}

if (isIdle()) {  … }

实际上,这种封装出行为的方式不仅仅适用于全局变量,把数据拿出来再用的情形也是经常可以见到的:

if (machine.getStatus() == IDLE) {  …}

封装的方式同上面一样,这里选择一种实现:

[…]

扎克伯格的一封信:关于Facebook IPO

MENLO PARK, CA (The Borowitz Report) – 在Fackbook IPO前夕,Facebook的创始人兼CEO Mark Zuckerberg 给全球股民发表了封公开信:

亲爱的股民们:

    这么多年来,你们已经在Facebook上浪费了你们的时间 ,接下来,你们会得到浪费你们金钱的机会。

   明天是Facebook的IPO,并且我知道你们一定在想,Facebook怎么就和2000年的.COM泡沫不一样啦?

首先,我想告诉你们,以前那些糟糕的dot-com公司玩的是概念和炒作,而没有真正的商业价值。而Facebook不一样,也就是说,我们Facebook是建立在强大的以“疯狂的小鸟”和“一群想像中的羊”的基础上的。

其次,Facebook是世界上最成功的社交网络,我们的用户最近才发现,这个社交网络让人们分享了数以万计别人根本不感兴趣的信息。

第三,当某人点击Faceback广告的时候,我们就会挣到钱。而且我们知道,点我们广告的人都不是故意点击,成百万的人点我们的广告是因为那时他们喝醉了。我们完全从iTunes偷到这个有创意的想法。

最后,如果你买我们的股票,你将永远不会孤独。据调查,在过去几年里使用facebook的全球9亿用户,他们都有轻微或中等程度的大脑损伤,这影响了他们的作正常判断的能力。所以,这些人都成为你的朋友——Facebook的股民。

有了你的帮助,如果明天一切都照计划进行,Facebook IPO将会募到1000亿美金。这是个什么概念,这相当于4到5个摩根大通银行损失的钱。

最后一件事:我,Mark Zuckerberg,是否会因此IPO获得180亿美金? 也许,我正在考虑把希腊买了,但就算是这样,我还是有180亿美金。 LOL.

Friend me (粉我),

Mark

(新闻来源:http://www.borowitzreport.com/2012/05/17/a-letter-from-mark-zuckerberg/)

(转载本站文章请注明作者和出处 酷壳 – CoolShell.cn ,请勿用于任何商业用途)

————————============ 感谢 42qu.com 为本站提供 VPS ============———————— 您可能也喜欢: Facebook全球关系网 Facebook 的系统架构 Quora使用到的技术 程序员的相关笑话(一) 程序员的相关笑话(二) 无觅 相关文章 2011年07月04日 […]

韩寒的事,不弄个水落石出,不能算完

1. 是否可以质疑韩寒?

暂不论“为什么质疑韩寒”,先问问“是否可以质疑韩寒”?

——当然可以。

首先,质疑本身,不会改变真假,真的不会因为被质疑就变成假的,不是坏事儿;假的被质疑而后被证明是假的,也不是坏事儿;假的被质疑被证明之后依然被当做真的,那才是坏事儿。

其次,不管什么原因,一旦质疑开始,除非真相大白,有什么理由停止呢?

2. 为什么质疑韩寒?

根据过往经验,我自认不是一个很有“怀疑精神”的人。在人们普遍质疑雷锋之前,我没想过从小接受的雷锋形象、雷锋事迹哪儿不对。在没有人质疑韩寒之前,我也没有过一丝想要质疑他的念头。相反,偶尔看看他的博文(没读过他的任何其它文字),也只关注内容,而后也觉得内容不错,曾向朋友和学生夸奖过韩寒。

质疑是由他人开始的,而我是后知后觉,晚了好几拍才开始关注此事。最初关注的时候,也更多关注人们的看法及其来源。再后来,我也开始对韩寒持越来越多的怀疑态度。理由非常简单——韩寒从未正面回应质疑——若干次的回应,都是不光明不磊落的。

后来韩寒出版了“手稿”——这应该是很多人认为的“正面回应质疑”了罢。可在我眼里,这所谓的“正面回应”,恰恰增加了更多的怀疑——“手稿”中由大量因心不在焉而发生的错误,这种错误不会发生在创作过程中——诸如“限不得”(恨不得)之类。

迄今为止韩寒被质疑之后的言行,没有任何一件让我消除怀疑,我又如何停止质疑?

(补充一个:当韩寒声称自己在高中的时候彻夜研读二十四史的时候,我不仅开始真正怀疑韩寒代笔,也开始瞧不起韩仁均——他们父子俩可能以为二十四史是一本书或者几本书……)

3. 韩寒是否有义务回应质疑?

原本没有。我并不同意韩寒的所谓“所有的作者都无法自证”之说,但,我也不觉得韩寒有义务回应质疑。韩寒可以完全不回应——策略也好,个性也罢,如果韩寒完全不回应,也没有人会、也不该仅仅因为他不回应而怪罪他。

4. 我什么时候开始铁了心要等到水落石出?

其实,韩寒是否代笔,还真的没重要到什么地步。关于假的太多,“现在除了妈妈之外,都可能是假的”之类的话,二十年前国内就流行了。真假很重要,但是,我也知道真假在中国,在中国的很多人眼里根本不重要。如若我认为重要,我自己坚持就是了,顶多希望别人也坚持,但要求别人也坚持,那就是我过分了,我的意思是说,过分天真了。

韩寒作势要起诉方舟子的时候,我彻底改变了态度。这事儿还真得追究了——原本顶多是笔墨官司而已。但,韩寒起诉的做法,触及了底线:质疑,是每个人的基本权利,在我眼里,这比言论自由都重要。

韩寒既然把“被质疑”和“被诽谤”等同起来,到了法庭上,就必须拿出证据——质疑他的人中,像我这样的,都在等韩寒拿出证据,以释困惑。然而,他很快就撤诉了。到了5月份,李海鹏的《人物》专访中说,那起诉是假的,至于撤诉的原因,韩寒表示自己不方便说,说了李海鹏也不方便写……这种如此乖巧地把责任推给党的做法,只能让韩寒显得更为吊诡。

5. 别告诉我韩寒的文章(不论是否代笔)也有可取的内容。

这是最无聊的辩护——没有之一。那文革中被打死的也有确确实实的坏蛋,难道这能为文革辩护吗?那所有的邪教书籍里面也弘扬一些美德,难道这就能为邪教正名么?

在没有代写的情况下,哪怕一点点的优点,都值得珍惜,可是,如若是代写的,那所有所谓的优点,又何足挂齿?

6. 这事儿有意思么?

有。起码对我来说,有。并且很有意思,有各种意思。

7. 你有什么证据?

我目前的立场,都基于网络上的讨论。我并不认为“间接证据”无效——在缺乏“直接证据”的情况下,我们只能通过“间接证据”判断。事实上,要是没有“直接证据”就不能判断的话,大多数罪犯都可以轻松逍遥法外,进化论也没办法接受了——扯远了,但,事实是,现在证据越来越多了,除非视而不见。

8. 如果有人质疑你写的书是代写的,你怎么办?

就想到会有人问这个,所以才写了第3条——可惜,就是有人阅而不读,于是,他们依然会好像占了什么理一样质问这个。

如果有人这样质疑,首先,我没理由、也没必要一定回应。至于理由,参见第三条。质疑就质疑呗,被人质疑,很奇怪么?

其次,如果我选择回应,不会选择用什么悬赏的办法,也不会威胁对方“叫你吃不了兜着走”,也不会攻击对方说对方的孩子是对方老婆偷人的结果,更不会仅仅对方质疑这个就去法院起诉(既然不会起诉,就不会撤诉)。如果选择回应就应该用最直接的方法;关于这点,冯唐和王朔都一针见血地明说过——有兴趣大家自己到网上查。

另外,我的那本书书是如何成书的,知者无数——因为从初稿就开始全部公开在网上(内容在书写在互联网上之前,在课堂里也讲了7年,每年听众超过万人),而期间如何修改,如何丢掉数据重新写过,大家都知道。尽管我自己的服务器坏过,但互联网神器archive.org上有从2002年开始的所有痕迹(最初我用的域名还是xiaolai.net)。所以,其实不会有人有同样的质疑的——因为没什么可质疑的。之前,海岩被质疑,人家也没做什么别的事情啊,只是拿出自己的手稿(当然不是漏洞百出的东西),然后就该干嘛接着干嘛去了。没做错事情,怕质疑做什么?

9. 你说话要负责任!

既然说了,就不怕承担责任。如果韩寒因此控告我诽谤,我随时应诉。

Android是个好系统

  仅凭一个Android,Google完全有资格领好人卡。因为Android开源,就可以放心大胆的做各种“美化”、“定制”、“深度定制”。而Google对这些行为不能抗议、强烈谴责、严正交涉,只能不满和深表遗憾。

  对于Android在中国的情况,Williamlong认为:

  @williamlong: 对于互联网公司做手机,我会鄙视那些所谓“深度定制”而实际是删除谷歌帐号的那些平台,这不是国家政策方面的问题,谷歌应用删除了无所谓,用户可以自己安装,但是将谷歌帐号删除掉之后,用户只有通过刷机等复杂操作才能安装谷歌应用商店和其他谷歌应用,这对于用户来说是一种恶意绑架行为。

  然而大多数中国Androidr不这么想。身边的人很少用Google的服务,一是长久以来对Google没印象,甚至是因为用了Android才知道有Google这个公司;二是Google的服务在中国并不好用,因为Google有“互联网的至高荣誉——GFW认证”。Google的服务在中国也有不少替代品,而且做得相当符合国人口味。   

  比如以下场景可以经常见到:

  Gmail

  Gmail是什么?是邮箱吗?哦,我有QQ/Sina/网易邮箱,而且不在手机上用,太费流量。

  或者

  邮箱啊,我只在注册用户时用一下,从公共邮箱下课件什么的,其他很少用邮箱的。

  联系人

  不用QQ通讯录吗?超好用的!

  Gtalk

  Gtalk是什么啊?有人用吗?QQ多好用,用的人也多,微信也超好的,飞信还能发免费短信呢!

  Google地图

  百度地图也很好啊,凯立德定位特快

  Android Market/Google Play

  不是安卓市场?国内那么多市场呢,豌豆荚还能搜索那些市场,超好用的。

  用Android的未必是谷粉,只是因为Android是除了iPhone以外最火的手机而选Android的不在少数。而且各个搞Android开发的中国公司都在极力的搞本地化、去Google化。当然他们做的都很好,以至于不少Androidr都不用Google的服务而用更符合国情的国产应用。对这些Androidr来说,Google应用、Google账户几乎不会用到。去Google化的同时小动一下手脚也不会有太大反响。所以说国内Androidr一般直接无视这种“恶意绑架”,“随你便,反正没我事”。

  开源与流行

  Android是开源的。而开源只是流行的因素之一。在一般人眼里开源是免费的“雅称”。在iPhone与Android之前,在那个还用笔戳屏的年代,就已经有了搭载开源的Linux的智能手机,但是用Linux手机的人少之甚少。因为Linux没人管,硬件商也只是借来一用。与WindowsMobile不相上下的复杂操作,又缺少M$对WM那样的支持与宣传。Linux自然用的人少。虽然Linux开源,可以根据自己需要编写软件,但普通人毕竟不是程序员。免费又怎样,用户只是想拿来就用,所以付费也可以。而Ubuntu和Android这样的开源货会火起来,我觉得完全是因为Canonical和Google的支持与宣传。Canonical和Google的“支持”大概是让Ubuntu和Android越来越傻瓜化。智能产品做的越傻瓜用户越多,真是讽刺呢。

  由于Android开源,则会产生各种第三方固件。这样使Android有了可以在各种设备上运行的条件。因为Android开源,各硬件商就能借来一用。比起价格昂贵、高高在上的iPhone/iPad,各种便宜的Android更亲民一些。与其卖一个肾换来一两年的虚荣,不如省两三个月饭钱换来一两年的平淡日子。

  比起Apple一年一个iPhone/iPad,对iOS修改不用像Android那样考虑很多。Google则干脆不考虑,让那些硬件商们自己弄去。因此就产生了Android严重的版本分裂。不过即使版本严重分裂,单看每个Android设备,都是不错的设备。尤其现在ARM的Cortex-A8/9普及和Android2.3/4.0的普及,即使是百元山寨板、千元智能手机也有不错的体验。

  另外,iOS是重应用的系统,而Android则是重文件的系统,这点很像Windows。只要把文件拖入存储卡/内存,在Android上能找到就能用。Android上对文件的操作也比iOS来的爽快。因此从Windows迁移到Android不会有多大的障碍。

  Android的流行则会引来一个问题,“基于Android的发行版”,我先称之为“再发行版”吧。虽然像Ubuntu这样的传统Linux发行版不怕再发行版,因为Ubuntu本身就是Debian的再发行版。不过Google是要靠Android赚钱的,Android的再发行版一般都会做“去Google化”,这样很伤Google。

  去Google化

  像著名的第三方MOD CyanogenMod,就默认不包含Gapp,不过CM同时也放出Gapp包,用户可以根据自己需要来安装。国产神ROM MIUI也要开始默认不包含Gapp了。Amazon的Kindle Fire也积极的去Google化。有了Fire做先例,以后再出看不出一点Google味的Android,也不足为奇了。

  开始我很鄙视去Google化,鄙视用Android不用Google服务的人。直到我用了一款国产山寨板(蓝魔音乐汇W19)。

  W19虽然用的是Android4.0,但几乎没有一个Gapp。而且定制的ROM上几乎无法安装Gapp。设置里就差抹掉的“用户帐户”根本没法使用,Market/Google Play就更不可能用了。

  为什么要去Google化?我不知道,有那么方便的市场为什么不用?国内因为网络不好也就算了,为什么连CM也去Google化?也许去Google化的手机更像一个功能机,简单好用。也许第三方市场/论坛资源比官方市场更好。

  离线使用未必不好。我的W19现在基本就是一个彩屏Kindle,偶尔玩玩游戏,视频都不怎么看,连网都不上。用的最多的功能是看闲书和各种手册。什么都干不了的W19反而让我反思我们用平板到底是为了干什么。为什么什么都干不了的iPad会打败什么都能干的AcerPad。

  Google真是好人呢,Android再怎么去Google化依然可以用的很爽。

  One More Thing……

  Android离开中国(俺的妄想)

  Google是赚Android上的广告的钱吧,用户也不在意是谁在发广告。如果某个胆大的团队敢触及Google的广告服务,换成自己的广告服务,那么Google也会有所行动吧。

  来源:CarlNERV投稿,原文链接。

评论《Android是个好系统》的内容…

相关文章: 传工信部禁止移动终端使用Google 开发商对Android兴趣持续下降 解析Android Market更名Google Play Store 为什么Android平板电脑已经失败 谷歌中国Android Market前景暗淡

微博:新浪微博 – 腾讯微博 – 论坛 月光博客投稿信箱

核心版本——Programmers(37)

载于《程序员》杂志2012年第5期。

这个系列的漫画讲述程序员——这种神秘人类的囧事,故事多来源于我身边的程序员朋友,且以互联网开发背景为主。

如果你有什么可乐的关于程序员的故事、对话、代码,愿意通过漫画的形式分享,请给我发邮件。

移动开发者——Programmers(36)

载于《程序员》杂志2012年第4期。

感谢 Stony Wang 同学作为Android开发者的代表向我提供了各类悲剧list。

这个系列的漫画讲述程序员——这种神秘人类的囧事,故事多来源于我身边的程序员朋友,且以互联网开发背景为主。

如果你有什么可乐的关于程序员的故事、对话、代码,愿意通过漫画的形式分享,请给我发邮件。

ThoughtWorks校园行,第二步

自从迈出了ThoughtWorks校园行的第一步,西电的校园活动就一次次进行下来,我们讲了如何写代码,讲了完整的开发过程,后续的一系列校园技术讲座也已经排上了日程。

其实,单以效果而言,技术讲座所带来的影响是有限的,对于参加讲座的学生来说,除了知道很多新名词、新做法,多半也就是看个热闹。直接动手实践,才是一个更好的做法。

感谢我们优秀的市场MM,她为我们打开了一片新天地。感谢西安交通大学软件学院的领导具备的卓越眼光,为他们的学生提供了一个接触外面世界的机会。

于是,我们有了一个新的机会,在西安交通大学开设一门软件开发的课程。

这门课,我们称之为“现代软件开发”,其目的就是为了告诉同学们,不同于传统方式的开发方法。其实,我们本可以叫敏捷软件开发方法,但我着实不喜欢这个名字,因为这已不是我追求的东西,我只想把一些好的东西告诉同学们,所以,选了一个不容易过时的名字。

我们是这样设计的这门课,采用上下半场的方式运作。上半场,我们会介绍一些基本的开发方法,比如整洁代码,比如重构,比如自动化等等。而下半场,则完全是实践。我们选取了一个项目,按照我们的方式运作了一个项目,我们的同事会与同学们结对,让他们直接体会最原汁原味的ThoughtWorks开发方式。

就在这个周末,这个系列课程终于迈出了第一步。

第一次课基本上算是一个课程介绍,让为有兴趣选修这门课的同学了解这门课,以及我们的上课方式。我们讲了公司里如何做软件,还演示了结对开发和TDD。

第二步就这样迈了出来,在接下来的一段时间里,虽然要牺牲一些业余时间,但这也是一个很好的尝试,让我们的课程更加系统化,也给了我们的同事一个很好的锻炼机会。

我们的同事在课程的结尾送给同学们一句话,与其周末逛街打DOTA,还不如来写写代码。嗯,就是这样。

软件开发中的火车模型发布模式

《启示录:打造用户喜爱的产品》这边说第一张就讲到了“许多成熟的互联网公司都在使用火车模型发布模式”,对于火车模型发布模式具体是什么意思不太清楚,于是上网找资料,发现网上很好又介绍火车模型发布模式的,可能是翻译不一致导致的结果。对于火车模型发布模式其实也是很好理解的,下面就是我找的一个关于火车发布模式的案例,来自于FireFox开发团队。

Firefox目前正在采用的开苏发布过程其实就是火车模型发布模式,使用心得模式后一个新特性从实现并且进入mozilla-central分支到发布到用户手里只需要12-18周,并不向IE浏览器的更新以用一样要几年的时间。如此的快速发布过程给整个项目带来了更好的敏捷性和更强的稳定性。在每个发布周期的测试和稳定阶段可以覆盖更多的用户来帮助FireFox的开发人员更早的发现和解决问题,保持在每次发布质量上的信心。

下面就要介绍下Firefox的发布流程。每个独立的发布火车(新的发布过程采用火车模型,固定的“发车”时间,特性的发布取决于该特性是否赶上最近的火车发车时间)包括6周的开发时间加上12周的稳定时间:

新的开发成果不会直接发布到Aurora和Beta分支上。这些分支需要被开发人员和社区测试人员共同测试完方可,如果发现开发中存在程序问题或者BUG,就需要先解决问题。如上图所示,您能够看出发布周期基本上是稳定的18个星期。

Aurora和Beta分支基本上完全关注于稳定性和测试,同时,很多的工程师也在同步开始新的开发工作,所以,如果看更大的一张图表的话,下面是真正进行的过程:

在Aurora和Beta分支上经历的12周时间里,Mozilla开发社区并没有在闲着。他们会继续为后面的发布开发新的特性和bug fix。每六个星期,他们的工作会被选择性的合并到Aurora分支,继而合并到Beta分支上。观察上面的图表,您会发现很重要的一点,就是:每六个星期就会有一个新版本的Firefox发布,而不是12周或者18周。

参考地址:http://blog.mozilla.org/channels/2011/07/18/every-six-weeks/

Related posts:

IE PNG Fix 2.0 数据分析中常用的数据模型 MySQL 初级教程(一)

Category

Archives