弱者的悲哀

3月31号,去大江东考场练习科目三,包括自己在内一共五个学员,早上七点半就到场地了,那时候还没有多少人。我是第四个上车的,那时大约到九点了。我前面那个女学员不知是因为刹车太急还是转向灯没开的问题,被教练逮到机会一顿辱骂,说什么没带脑子,说了多少次还记不住,之后都是很难听的话。中间我曾想制止和反击教练,不过转念一想,我若是替她鸣不平,教练肯定会说跟我在骂她,跟你没关系什么的。于是,我决定等待。到我了,上车挂一档的时候,感觉这车的档位和上次开的车的档位手感不太一样,于是重挂了几次,又问教练是不是挂对了。教练这时开喷了,说你问什么,叫你不要问,听着就行了,接着又开始了他的习惯性辱骂。没等他说完,我就以两倍的音量回击他。他先是怔了一下,应该是没想到会有学员反驳他,接着跟我吵。不过明显语气减弱了许多,说什么这样是为你们好,让你们记住云云。同车的学员也都劝我,少说两句,教练也是为你好之类的。… Read the rest

Scalar Data

Numbers

All Numbers Have the Same Format Internally

Internally, Perl computes with double-precision floating- point values. This means that there are no integer values internal to Perl—an integer constant in the program is treated as the equivalent floating-point value. Examples:… Read the rest

Bad design

最近项目中有个需求是关于下载进度条的。原来我们在 cloud 上面下载文件,点击下载之后,实际上要先计算出要下载哪些文件(因为可能包含文件夹,文件夹内的文件需要网络请求才知道),然后开始真正的多线程下载。我们把之前的计算阶段称为 calculating 阶段或 preparing 阶段,后面的下载阶段称为 downloading 阶段。如下两幅图所示:… Read the rest

我与地坛

上个周末读了史铁生的《我与地坛》,对他的北京话印象深刻。北京方言和河北方言差不多,读他回忆的那些故事,不觉间想到了自己的童年。摘录其中的几段暂作为读书笔记吧。

我的梦想

  • 也许是因为人缺了什么就更喜欢什么吧,我的两条腿一动不能动,却是个体育迷。
  • 我希望既有一个健美的躯体又有一个了悟人生意义的灵魂,我希望二者兼得。

好运设计
史铁生20岁时双腿瘫痪,很不走运。所以他常常在床上想如果有来世,自己会有一个什么样的命运。他设想了一个完美的命运,一个完美的人,最好生在一个普通知识分子家庭。在乡下不好,在贵府名门也不好。下面这段对于生在农村的我来说感触很深。

  • 降生在什么地方也是件相当重要的事。二十年前插队的时候,我在偏远闭塞的陕北乡下,见过不少健康漂亮尤其聪慧超群的少年。当时我就想他们要是生在一个恰当的地方他们必都会大有作为,无论他们做什么他们都必定成就非凡。但在那穷乡僻壤,吃饱肚子尚且是一件颇为荣耀的成绩,哪还有余力去奢想什么文化呢?所以他们没有机会上学,自然也没有书读,看不到报纸电视甚至很少看得到电影,他们完全不知道外面的世界是什么样子,便只可能遵循了祖祖辈辈的老路,日出而作日入而息,春种秋收夏忙冬闲,日复一日年复一年。光阴如常地流逝,然后他们长大了,娶妻生子成家立业,才华逐步耗尽变作纯朴而无梦想的汉子。然后,可以料到,他们也将如他们的父辈一样地老去,惟单调的岁月在他们身上留下注定的痕迹。而人为什么要活这一回呢?却仍未在他们苍老的心里成为问题。然后,他们恐惧着、祈祷着、惊慌着听命于死亡随意安排。再然后呢?再然后倘若那地方没有变化,他们的儿女们必定还是这样地长大、老去、磨钝了梦想,一代代去完成同样的过程。或许这倒是福气?或许他们比我少着梦想所以也比我少着痛苦?他们会不会也设想过自己的来世呢?没有梦想或梦想如此微薄的他们又是如何设想自己的来世呢?我不知道。我不知道。我只希望我的来世不要是他们这样,千万不要是这样。

记忆与印象1

  • 故事有时候是必要的,有时候让人怀疑。故事难免为故事的要求所迫;动人心弦,感人泪下,起伏跌宕,总之它要的是引人入胜。结果呢,它仅仅是一个故事了。一些人真实的困苦变成了另一些人编织的愉快,一个时代的绝望与祈告,变成了另一个时代的潇洒的文字的调遣,不能说这不正当,但其间总似拉开着一个巨大的空当,从中走漏了更重要的东西。

这段其实是说史铁生的“姥爷”,一个国民党抗日军官,在“解放”时被小人算计,最后被执行枪决。他说这其中必定隐匿着一个故事,悲惨的,或者竟是滑稽的故事。但他不想去考证,不想让这成为一个故事,一个供后来人消遣的故事。

记忆与印象2

  • 模仿电影里的行动,是一切童年必有的乐事。...... 因而,曾有一代少年由衷地向往那样的烽火硝烟。(“首长,让我们上前线吧,都快把人憋死了!” “怎么, 着急了? 放心,有你们的仗打。”)是呀,打死敌人你就是英雄,被敌人打死你就还是英雄,这可是多么值得!故而冲锋号一响,银幕上炮火横飞——一批年轻人撂倒了另一批年轻人,一些被怀念的恋人消灭了另一些被怀念的恋人——场内立刻一片欢腾。
  • 我独自看那“编剧”后面的三个字,早已懂得:有为,与爱情,原是风马牛不相及的两个领域。但暂时,亦可在心中长久,而写作,却永远地不能与爱情无关。

想念地坛

  • 再看那些老柏树,历无数春秋寒暑依旧镇定自若,不为流光掠影所迷。我曾注意过它们的坚强,但在想念里,我看见万物的美德更在于柔弱。...... 柔弱,是信者仰慕神恩的心情,静聆神命的姿态。...... 但要是“爱”也喧嚣,“美”也招摇,“真诚”沦为一句时髦的广告,那怎么办?惟柔弱是爱愿的识别,正如放弃是喧嚣的解剂。

读这部分的时候,突然想到某人的温柔。我想,温柔也是一种很难得的美德吧。

  • 写,真是个办法,油然地通向着安静。写,这形式,注定是个人的,容易撞见诚实,容易被诚实揪住不放,容易在市场之外遭遇心中的阴暗,在自以为是时回归零度。把一切污浊、畸形、歧路,重新放回到那儿去检查,勿使伪劣的心魂流布。

我想,不仅是写,读也是这样。读到文中几段反思自己的恶的部分,我看到了自己曾经的虚伪。很多事,并不因为没有人追究你,你就能逃脱惩罚。也许在某个午后,往事会一幕幕袭来,丑陋的内心暴露在阳光下,痛苦与悔恨充斥心间,而你却什么也做不了。借用《一个女孩》中的一句话:当你无法说抱歉的时候,你的错误就变成肉中刺。

希望在这个浮躁的世界,仍然能做一个真诚的人,诚实的人。… Read the rest

走出迷惘

今天是2018年的第一天,回想过去的一年,忙碌、希望、难受、顿悟、反思,经历了很多,觉得有必要写下来(其实还是跟风和矫情),作为成长的见证,然后为新年做一个新计划。

时间回到2016年8月,辞职后找工作,然后去了THS。 事后证明这是一个错误的决定。9月入职,感觉工作很不开心。10月国庆期间做了一个手术,感到很烦。11月从THS辞职,然后又是找工作。这次没有想像中那么顺利,西溪那边基本都是创业公司,不想去。当时收养了一小猫,留恋在西溪的环境,不想去滨江。后来觉得可能真的无法在西溪找到工作,没办法来滨江了。12月来到Glority,感觉还行吧。不过可能还是自己适应能力比较差,加上没有自信,前期做的并不好。我得感谢我的领导CCC,关键时刻给了我很多启发,也让我找回了自信。后面的工作算是走上正轨了吧。

对于我,2017年的关键词应该是忙碌。工作上很忙,零经验做windows界面开发,有很多东西要学。同时空闲时间也读了一些书,看了几部可爱的动漫和一些老电影。

读书

经济学原理(by 格里高利・曼昆)
还在THS的时候,同事YY给我推荐了这本书。16年读了《微观经济学》分册,17年读了《宏观经济学》分册的一部分,读完感叹原来教材还可以这样写。理论介绍得很充分,很详细,然后每章都有对应理论的实例分析和练习题。书中介绍的很多理论,如比较优势,供求定理,歧视经济学等,都对生活中的经济现象做了非常好的解释。我觉得这本书应该成为大学必修课的内容,它值得每个人学习。
今年如果有空,还想再复习并整理一遍《微观经济学》,然后读《国富论》。

正义的成本(by 熊秉元)
这本书是初恋推荐给我的。不过我一直没有去看,直到17年才在看完经济学后想起来。这是一本法律经济学的入门读物,书中的大部分内容现在已经不大记得了,大概是对生活中的现象从法律和经济两方面做出解释和指导。这本书没有《经济学原理》中那么多的理论,更多的是针对生活的案例提出一些比较好的思考方式。印象最深的是其中提到的2种思维方式:假设性思维和财富最大化。

丑陋的中国人(by 柏杨)
这本书是一本杂文集,其中收录了柏杨先生在各地的演讲稿和发表在杂志上的一些文章。书中指出了中国人的各种丑陋之处:脏、乱、吵,窝里斗、不团结,死不认错,讳疾忌医,明哲保身,没有独立思考能力和鉴赏能力,奴性,崇古,不求上进,权势崇拜,只我例外,不讲是非,只讲“正路”,责备贤者等等。柏杨先生把中国人丑陋的原因归结为“酱缸文化”,大概就是传统文化中的糟粕的集合。这本书更多的意义在于自省,对照书中的各种陋习,时刻反省自己。

野火集(by 龙应台)
这本书是龙应台在80年代所发表的抨击时弊的文章的合集。当时台湾还处在集权统治之中,这本书里的文章就是针对当时的种种黑暗、丑陋的社会现象和制度进行抨击。尽管这本书写在80年代的台湾,但其中所涉及的黑暗和丑陋在当代大陆仍然存在,其中的评论放到现在仍然发人深省。在台湾民主化后,人民开始被另一种敌手所困扰:一种以庸俗浅薄为时尚、以“绝对娱乐”为目的、以行销消费为最高指导原则的生活哲学。但我感觉这好像不单单是台湾遇到的问题,而是世界上很多地方都在面临的问题,包括大陆。摘录其中的一句:我也确信那个不公的体制得以存在,是因为个人允许它存在;比体制更根本的问题,在于个人。

一个女孩(by 陈丹燕)
这是陈丹燕的一本自传体小说,写的是她小时候(文化大革命时期)的一些经历。主要写了那个年代发生的种种匪夷所思和令人恐怖的事,以及她自己的感受。总的来说,读起来是那种平静中带着悲伤的感觉,也有一点矫情。摘录其中一段如下:老人脸上诚实地面对孩子的神情,像一根针一样刺痛了我,那里我明白了,人的心都是那样柔软,柔软的心是那样珍贵。当它呈现在你面前时,就像跌破了皮肤的伤口,干净、新鲜,不能用手指碰,一下也不能碰,不然那心会很疼,但人有一颗柔软干净的心是多么好。

奇怪的是它被归类于儿童文学,我并不认为儿童能在没有相关背景的情况下读懂。

除此之外,还读了弗洛姆的《爱的艺术》,主要讲了怎样自爱和爱人;野夫的《江上的母亲》,主要是野夫的回忆文章和散文,文笔很好;还有前同事yjy推荐的《刻意练习》,主要讲了学习的方法,在某一领域成为专家或者杰出人物需要“刻意”地练习。

技术方面,读了《人月神话》,《Effective C++》,《clean code》,《Professional C# 5.0 and .NET 4.5.1》(Part 1)和《WPF编程宝典》(看了一部分)。其中,《Professional C# 5.0 and … Read the rest

迷信权威

 一直以来,我都是一个迷信权威的人。可能是因为没读过什么书,所以独立思考能力很差。上学的时候把课本和老师当成权威,上班后把领导当成权威。既然觉得他们是权威,心里会认为他们说的做的即使不完全对,也肯定是有一定道理的。

 还记得有个同学跟我说她在公司就是看代码,领导不信任她,所以不让她写代码。我听了一方面觉得很遗憾,碰到这样有性别歧视思想的领导是一种不幸。另一方面觉得领导是不是有领导的考虑。这几乎是我的下意识。后来,当我遇到其他的领导的时候,我才发觉我错了。我意识到,我们有很多优秀的开发者,但很少有优秀的管理者,甚至是合格的管理者。大部分做技术的转管理其实并不天生具有管理的经验,也因此并不是开发做的好管理就一定做的好。

 我想产生这种奇怪的想法源于我一惯迷信权威,缺乏独立思考。觉得领导之所以当上领导肯定是比一般人要厉害,做出的决策安排肯定有其合理的地方。现在又想起来这件事,发现性别歧视就是性别歧视,这个并没有什么可洗的。

 但是在这里想向那个同学道歉,真的很对不起。希望她没有因为我的话而怀疑自己,失去做开发的信心。

 有时候会想自己不经意的一句话,可能就会对别人产生误导和伤害,感觉还是要多读书,提高自己的知识水平。另外,谨言慎行,与大家共勉。… Read the rest

人月神话

抽空把《人月神话》复习了一遍,回顾自己近期的工作,想对书中的一些观点谈谈自己的感受。

  1. 编程行业“满足我们内心深处的创造渴望和愉悦所有人的共有情感”,其提供了五种乐趣

    • 创建事物的快乐;
    • 开发对其他人有用的东西的乐趣;
    • 将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力;
    • 面对不重复的任务,不断学习的乐趣
    • 工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动——其存在、移动和运转方式完全不同于实际物体

    最近公司接了一个活,目标是把一个windows上的软件产品做成跨平台的,也就是windows和mac。雇主那边写了一个类似于WPF的框架,目前需要我们把原来用MFC写的界面换成用他们的框架写成的界面。写了2天之后我发现这个工作大部分是体力活。首先你需要把原来的界面用他们的框架画好,就跟写WPF界面差不多。然后把原来界面中的逻辑重新实现一下。因为没有文档,全靠参照前期领导写的代码和问同事,所以写得比较累。继续写了几天以后,感觉这个东西没有给我带来任何成就感。我觉得我成了流水线上的工人,原来编程带给我乐趣都不存在了,有的只是重复和被push的压力。原来觉得编程是一种脑力劳动,现在发现在你掌握了一定的技术基础之后,有些事情就变成了体力劳动。对于这种工作,我的态度是按时上班,按时下班,不付出额外的劳动。因为我觉得这个工作不值得我付出哪怕多一点的精力。它对程序员而言是一种痛苦。加班加点地做这种痛苦的事只会使自己逐渐丧失对编程的乐趣。所以我一直在自学一些觉得有意思的东西,始终让自己保持对编程的新鲜感。我知道我还要写几十年的程序,保持兴趣才能让我不断进步。

  2. 所有的编程人员都是乐观主义者,“一切都将动作良好”。
    这个是我感受最深的一点。从我非常有限的编程实践中,我发现从project manager到一线程序员,普遍都对进度做了过于乐观的估计。书中提到了几个点说明为什么进度常常不是按照我们估计得那样进行。

    • 由于编程人员通过纯粹的思维活动来开发,我们期待在实现过程中不会碰到困难。但是我们的构思本身是有缺陷的,因此总会有bug.
    • 围绕着成本核算的估计技术,混淆了工作量和项目进度。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
    • 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通。

    做乐观的进度估计很多时候来自于客户或者雇主的压力。项目经理会受到来自于客户的压力,一线开发者又会受到同事和项目经理的压力。然而实际完成的时间并不会由于估计的时间少就会早完成。从实际来看,我完成的时间一般都是领导估计时间的3倍左右。我觉得我领导估计时间更多地考虑了代码变动所花的时间,而忽视了其它活动所花的时间。因此实际完成时间和预估时间相差比较大。

  3. 目标上(和开发策略上)的一些正常变化无可避免,事先为它们做准备总比假设它们不会出现好的多。
    程序员都希望需求是一成不变的,可是实际项目的需求往往一变再变。来公司3个月的时候,领导给了我一个小需求。要求在原来的界面上加几个控件,本来位置和个数写死就行了,后来变成了控件类型和数量都可以动态变化,控件位置也要动态改变。我原来实现的时候,只用了一层抽象去实现,这样实现起来可以满足需求,但可能很难应对变化。领导建议我把控件分组,增加一层抽象。后来雇主又要求控件布局也要动态变化,我才想到领导的先见之明。提前想想可能出现的需求变化,在前期适当增加一些抽象,往往可以更容易应对以后的需求变化。当然这个其实要求你对业务比较熟悉,能够对可能的需求变化做一些预测。后来我想写出好的软件除了需要精通各种技术之外,还需要熟悉业务,不熟悉业务很难做出有价值的决策。

  4. 缺陷修复总会以20%~50%的几率引入新的bug.
    在不断的改bug过程中,我越来越觉得这是真理。因为改bug需要你先理解原有的逻辑,对于老项目而言,特别是没有文档的老项目,理解它一个模块的各个逻辑是比较费力的。有时候你觉得你理解了它原有的逻辑,但你可能忽略了其中一个case,于是你的这次改动就引入了新的bug. 很多时候也是由于面前工期的压力,你没有时间完全理解原有的逻辑,只想快点解决这个比较严重的bug。这些都是导致新bug的原因。

  5. 即使是完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户——作者遗忘
    这条说的是文档的重要性。就我现在做的项目而言,是美国的外包项目。美国那边很重视文档,一开始就把详细的需求说明书(或者叫规格说明书)写好,并在以后根据情况随时更新。这样开发做起来就完全清楚要做什么功能,把功能具体做成什么样。原来待过一个月的A公司,经常是领导口头交待任务,具体做成什么样领导自己也不清楚,靠自己去问其他人,没有任何规范。我很难想像它这个项目能维护下去。现在做的这个项目已经有20多年的历史了,仍然能够维护下去,我觉得文档是很重要的一点。有什么问题,先看看原来的文档是怎么定义功能的,这样很多东西都有据可查。另外一点,代码中的注释也是极重要的,特别是针对特定case所写的代码,一定要写上注释,否则后面维护的人可能就倒霉了。在这一点上,我觉得我的领导给我做了很好的示范。通过他的code review,我逐渐明白了何时注释以及怎样写好的注释。

  6. 在未来的十年内,无论是在技术还是管理方法上,都看不出有任何突破性的进步,能够保证在十年内大幅度地提高软件的生产率、可靠性和简洁性。
    这是Brooks博士最重要的论点。他认为软件开发中最主要的困难是规格说明、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。软件开发中有一些无法避免的内在特性:复杂度、一致性、可变性和不可见性。正是这些内在特性导致了软件开发的生产率不会得到大幅度的提高。在他论文发表后的几十年时间里,软件开发领域出现了很多新的语言、工具、程序库,但这些只解决了软件开发中的一部分次要困难。
    不过,Brooks博士也提出了一些解决主要困难的方法。其中一个是需求精炼和快速原型。需求精炼是说,必须与客户进行深入的沟通,明确化客户需求中模糊的部分。但即使这样客户还是会有很多地方无法精确表达自己的需求,而改变传统的软件开发流程可能对解决这个问题有很大帮助,即快速原型。首先系统应该能够运行,即使未完成任何有用功能,只能正确调用一系列伪子系统。接着,系统一点一点被充实,子系统被轮流开发,或者在更低的层次调用程序、模块、子系统的占位符。这种方法要求自上而下的设计,因为它本身是一种自上而下增长的软件。
    读完这个论点,我还是有点云里雾里的。可能是经验太少,做的只是一小块,所以感触也不多。

最后,想用书中的一段评论来结尾,送给国内的开发者:
现实世界中的管理就是在更大程度上以人员的生命为代价,让他们更努力、更长时间的工作。经理们总是不停地吹嘘他们的人员的加班时数和能从这些人身上榨取更多时间的小把戏。这种情况下,开发产品的质量一定会下降,甚至惨不忍睹,因为开发人员唯一能控制的是质量,当他们不得不牺牲质量,痛苦地面对自己的工作,践踏工作的乐趣时,可以想像项目成本会大大增加,并且项目的发布往往伴随着一大批程序员的倒下。Read the rest

vps 负载过高,博客无法访问

最近晚上要整理整理博客, 发现博客经常无法打开。 查看 vps 进程发现 php5-fpm 进程占用了 CPU 的大部分时间,于是去网上搜了一圈,改了改配置文件,现在 CPU 使用率基本在 20% 以下,各服务都算正常,顺手做一个总结。

  1. 首先查看 /var/log/php5-fpm.log 文件,判断大概是什么问题。我的日志当时一直报这个 warning:

    WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 10 total
Read the rest

c implementation of “mkdir -p”

unix 下的 mkdir 函数只能在一个已经存在的目录下创建一个子目录,而常见的情况是创建一个多级目录,就像 shell 中的 mkdir -p 一样。看过工作中的不少实现,感觉不够简洁和清晰,于是找到了这个实现(链接:sharp2wing),应该可以了。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>

#define RWXRR (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH)

int make_path(const char *path, mode_t mode)  
{  
    char 
Read the rest