2013年5月6日星期一

时间紧迫症


时间紧迫症
  -- 时间紧迫的恐惧感

 昨夜至今天(20130421)我深刻反省自己,并勇敢地认识到:近几日得了时间紧迫症,内心反复触发起恐惧感。缘由来自最近工作的项目,一个对先前设计方案不断优化与改进的项目,这是之前出自我手的一个分享文件的设计方案(程序)。这段时间(10 天左右)关于项目优化的细节占据着我思维的大部分(80%),除了工作时间几乎占用全部之外,早晨睡醒脑子里第一件事情就是它或者说它把我从睡梦中叫醒,午休时候同样如此,晚上睡觉前最后一件事考虑的事情同样也是关乎方案的优化细节。

这些日子,优化细节不断从思绪中涌出,而且我总能很快付诸行动去编码、测试、观察性能、改动继续编码(反复)……如此反复的情况正是不断尝试调优的过程。这些日子,我的精力如此旺盛,在前面的日子丝毫不感疲倦……终于在昨天下午我深感累了,这种感觉似的来的异常快速,快速的令我不得不去反思回味前面的过程……其实,我应该更加理性一下,有些时候过于投入容易出现无法自拔的境地。

至此,项目的调优效果明显已达到原来预期的效果(甚至有点惊喜),至少可以满足领导们现在的期望了。因为所采用的优化方案不会对原来的设计结构大动干戈,而且经测试验证其效果理想,这样我们可以松了好几口气,可以暂缓下来去做其他比较紧急的另一个事情了,按理说现在我应该内心放缓轻松下来,不必为此事而费神了。但是,对于源源不断涌现出来的优化细节,我却抑制不住放缓不下来而是内心莫名紧迫起来恨不得立刻付诸行动去尝试……还有其他的工作事务安排所以容不得我去放纵。所以,后面这几天我的内心常常自我矛盾。最后深深发现自己累了,在网上搜索了解到“时间紧迫症”,与我的情况最相近了。

最后,我想简单地总结一句表达我想说的:由于最近工作的项目在不断地调优过程:思考、编码、测试、验证、改进、思考、编码……如此反复,导致近几日内心默默产生一种紧迫感,即一旦有思绪恨不得一蹴而就,立马付诸行动得以理想的优化结果,竟然一段时间乐此不疲精力旺盛。与如此情况最相近的就是时间紧迫症。累了,今日深刻自省,已放缓过来。
关于时间紧迫症,从网上捞到的定义(参考互动百科的时间紧迫症 ):
  时间综合症是指人们对时间的反应过于关注而产生的情绪波动、生理变化现象。时下,快节奏的现代生活,使都市白领感到时间越来越不够用,对事业的专注使人对紧迫的时间感到焦躁不安、紧张过度,这样会引发心率加快、血压升高、呼吸急促等症状。

咳咳……如上这些的表达都是为了尝试另我放松下来,我歇息歇息,满血再战!

记于20130421(完)

成功的老板都善于讲故事

成功的老板都善于讲故事
 -- 20130221 听Big boss 说价值观


刚好(20130221)今天是我第一天上班,中午就恰逢老板CEO(还有看看公司的CEO付总)请蜘蛛网兄弟们吃饭,前面说是老板与我们互相交流,而事后看来其实不如说是大家听他(们)讲故事,灌输一些价值观给我们,在此谈不上洗脑,毕竟老板说的那些事情我们相对比较认可的,而且也有类似娱乐新闻的趣味故事,笼统的回想回想,掐指算算聊到的话题,有:

1,聊自组网应用前景。嵌入在快传、手雷提供组网与数据传输服务,搭建平台。具体应用于文件分享、游戏平台等。

2,小团队作战能力精悍,反应敏捷效果突出。举了个例子几年前迅雷对手网际快车的第一作者(侯延堂),当时单枪匹马可以把软件设计的很好,但是后来交手给了十多人的团队反而没把握好方向了,慢慢做得不行了(落后了)。

3,迅雷也一直努力站在用户的利益。老板做迅雷牵扯的利益要面对股东、ZF、还有网民(用户)。老板技术出身一直崇尚技术但毕竟也是位商人,在当年中国环境办公司做生意必须学会与ZF妥协,要做好迅雷最终面对的是用户所以一直放用户利益至上。需要在股东与ZF面前争夺用户的利益。

4,在国内的互联网公司,老板最佩服的公司是阿里巴巴,在IT业界电商方面它不仅把技术、服务做得第一,还给中国提供了无数就业机会与商机。

5,在当今中国经商不得不与官员打交道,需要懂很多门道,还有老板风趣说趣事比如,有时某位官员觉得迅雷不听话想找茬,最后迅雷常常先找到了他的上司,这样就安然无事了。

6,迅雷碰到最多的官司关于版权问题……常常很难与好莱坞那边谈拢合作起来,可恶的美国人表面很斯文实际上都是很强势的(老板在美国生活了十年时间深有体会)。迅雷与好莱坞那边有过几次官司谈判,结果都不是很愉快。最后迅雷找到了好莱坞的爸爸(默多克)作为靠山,通过华人邓文迪(默多克第?任妻子)加盟了迅雷股东,这会迅雷在谈判上就有了足够的底气了。

7,老板说到自己一段不孝子的故事。2011年迅雷在香港、美国路演筹备上市(虽然最终未果),其年迈的父亲也一直跟随之儿子,但老父一直有个吐痰的习惯,当时在路演过程儿子正因此(不良)习惯而在父亲身上感到过羞愧……事后老板认真反省过,羞愧自己不孝,更应该体谅老父年老。日后要努力做好孝子。

记于20130221(完)

关于C++ 静态成员对象的一段小故事

关于C++ 静态成员对象的一段小故事
  -- 20130322 静态对象做单例的危险


  • 微博吐槽
(引用)近几天遇到一工作问题令我困惑不已,且又不是我所熟悉过的,直观体验完全感觉不出问题存在,但从大量测试统计能微微发现问题确实是存在的。诸多排除法之后还是觉得无从下手,甚至有违常理的感觉...一遍一遍review代码是件痛苦事情,最后靠着一点点改动希望接近问题所在,再得以解决。[睡觉][汗][吐] 附图:

btw. 吐槽不是重点,重点的是作为经验告诫提醒自己或他人。还有,吐槽了让我明天继续满血(激情动力)查问题。

  • 故事细节
今天,Review代码时发现一个比较重要线索,线索不是最终问题(即下载速度变慢)但也是问题是程序存在的漏洞,但是很可能两者关系紧密。要知道在查“莫名”问题的整个过程是相当枯燥乏味的,还得顶着上面人的催赶压力,所以发现一丝可疑线索是足够令人兴奋起来的,何况该线索又是看似比较重要。发现了线索、解决问题并验证、提交测试验证跑速度对比,这个过程是轻快的,之后就等测试对比结果。由于晚上十点钟才提交开始部署测试,只能等到明早上班时间才能出结果。所以,先不管了安心回家睡觉,静待明日结果,如上图。

线索(问题)描述:DLL模块存在两个单例对象,都是数据量比较大的类型,这两个单例对象都是以全局的static静态对象存在的。所以,只要DLL被LoadLibrary加载起来了,即使什么事情也不做,这两个静态对象也被生成了(包括构造函数做的具体操作也统统被执行到了),直至DLL被FreeLibrary卸载掉它们才会被析构的。具体情况详见如下示例。
  • 示例说明
 class A {
private:
   A() {
     ... ...
   }
   static A _s_a;

 public:
   static A* get_instance() {
     return &_s_a;
   }
   void do_work() {
   }
 }
 int main() {
  A *a = A::get_instance();
  a->do_work();
  ... ...
 }
> 问题在哪里?
 当程序还未执行到main()的A *a = A::get_instance();这行代码,对象_s_a已经被构造出来了,构造函数A()的逻辑也被执行了。
 当程序逻辑出现比较多这样的类型的静态成员对象,而且之间存在依赖关系的话,程序很可能在启动时候出现莫名其妙的问题。

  • 安全的单例
> 更好的单例解决方案是什么?
*** 简单的单例模板:
template < class _Type >
class singleton
{
public:
    static _Type* get_instance()
    {
        // 通过观察汇编代码,static 变量初始化在多线程下并不安全,
        // 多个线程同时首次调用 get_instance,可能导致 instance 被初始化多次
        // 所以,强烈建议在进入程序时显式调用一次 get_instance。
        static _Type instance;
        return &instance;
    }
}
推荐在进入程序时,显式调用一下 get_instance
线程安全,dll 被 Load 多次时安全
singleton 的缺点是,对象只在程序退出时被析构,
所以无法控制它的析构时机,不安全!

*** 扩展的单例模板:
template < class _Type >
class singleton_ex {
public:
    static void create_instance();
    static _Type* get_instance();
    static void destroy_instance();
};
安全性最高,但是需注意其特殊用法,要求:
在进入程序时,必须调用 create_instance
在退出程序时,必须调用 destroy_instance
线程安全,即使dll 被 Load 多次时也是安全的。
只给出单例声明的模板,对于具体的实现细节在此不必给出,请自行YY脑补。另,强烈推荐在create_instance用从堆数据动态分配内存并构造(即new操作)单例对象。

(引用)singleton与singleton_ex的对比
一般简单的单子,可以考虑使用 singleton
但是正因为它简单,所以忽略了一个问题,那就是多个单子类的析构顺序问题
如果多个单子的首次 get_instance 调用顺序是不确定的,那么它们的析构
顺序同样也是不确的。如果多个类的析构互相依赖,那么就肯定会存在问题。

所以,当有多个互相依赖的单子时,有两个解决方案:
1.使用 singleton_ex,进入程序时,按照期望的顺序调用 create_instance,
  在退出程序时,按照相反的顺序调用 destroy_instance。
2.使用 singleton,进入程序时,按照期望的顺序调用 get_instance,这样可以
  保证在 dll 被卸载时,多个单子按照与构造相反的顺序被析构。

所谓的“进入程序”,在 Dll 中,就意味着 DllMain 函数中的 DLL_PROCESS_ATTACH 分支
所谓的“退出程序”,在 Dll 中,就意味着 DllMain 函数中的 DLL_PROCESS_DETACH 分支


所谓的“dll 被 Load 多次”:dll 中的单子会面临一个问题,例如某个进程中,dll 被多
个模块分别 LoadLibrary 多次。因为单子的实质是 static 变量,故在整个进程中只有一个,
这可能是设计者期望的,也可能是设计者不期望的,所以必须要注意。
singleton_ex 中的 create_instance 和 destroy_instance 就设计了 _ref() 来处理被
多个模块多次调用。当然,singleton 不存在该问题。
>>>>> 对于更加牛逼的单例实现方案,参见Loki库的Singleton。还有,可参考我之前的另一篇关于单例的文章“单例安全性”

(完)