立场问题

立场问题是一个很严重的问题。在过去的年代,说某人立场不坚定,基本上就是说此人有叛变的潜质。

美国的总统大选秀正在如火如荼地上演着,对选民来说,要站在哪个党的立场上,这是个问题(不过据说现在的情况是布什连任已经基本成定局)

其实我写立场问题,是源于前几天有人在论坛里穿着公共马甲问了一个问题:

跟一帮朋友去玩,结果朋友们都叫小姐了,他不叫又不好意思,叫了吧又怕。

后来有一个家伙也穿了这个公共马甲回复道:

……(前略)问:要是那天你的上司和同事还有客户一起到了KTV,他们都叫了小姐,你叫不?答:(支吾中……)这个,这个,不知道呀……问:其实我也知道,上司叫了,同事叫了,客户也叫了,你不叫,也是为难。答:那是,那我就叫,哦,随便聊聊天,呵呵,这不就行了……问:少来,天下没有不吃腥的猫,人家都做,你不做,你面子往那搁?……答:(继续支吾中,心中很明白这个时候绝不能多嘴,嘻)良久……问:算了算了,不问你了,问也是白问!这样吧,以后要是碰到这种情况只要你不跟我说,不要让我知道,你做什么都不关我的事!……(后略)

站在朋友(或是后面回复中所说的,站在上司、同事、客户……等)的立场上,他如果不参加,那就是扫兴。而站在自己和家人的立场上,又不愿意参加。

要站在哪一边的立场上,这是个问题,而且是个大问题。

有消息称:《复旦大学经济学院原院长陆德明因嫖娼辞职》,如果那个补充的说法属实的话,可以大致猜测到:这个可怜的人多半是什么时候站错了立场,这次被人抓到把柄一次整到S了。虽然还是他自己的错,不该犯事,犯了事也不该落下把柄。不过如果有站错立场的前因,迟早还是会有后果的。

我们常常会被教导说:

在与别人的关系发生矛盾时,要多站在别人的立场上看问题。

但这在大多数情况下是做不到的,因为:

这里说的“别人”通常是复数。

这就注定了没有一个确定的“别人”的立场可以给你站。结果无非是:

在别人们的立场中徘徊,结果被认为是优柔寡断、没有主见;
或是站在某一个别人的立场上,结果被所有其它的别人认为是不公、有偏向;
要不就干脆是站在自己的立场上,被别人认为是刚愎自用、一意孤行。

比如伊拉克问题:要是站在伊拉克人的立场上,就会支持那些针对美国人的恐怖活动,凭什么要让美国人占领我们的国家,侵占我们的石油资源;要是站在美国人的立场上,就会支持布什的反恐战略,将恐怖分子消灭在本土以外,为美国争取更多的资源,以消除国内的通胀,发展经济,让大家过上好日子。

一种选择是否“正确”,是与其所处的立场相关的,而不是绝对的。

再以BLOG为例:

我要是考虑到我是搞技术的,我就应该写点技术方面的;但考虑到还有很多非技术的blogger们会来,我就得写一点八卦 。

还好我还可以选择写几篇技术后,八卦一阵。^O^

最著名的与立场有关的问题大概要算:

老婆和老妈一起掉到水里,应该先救哪一个?

站在老公的立场上,当然先救老婆;站在儿子的立场上,当然要先救老妈。

问题在于:

站在哪一边的立场上都是错误的!

有一个被认为经典的回答是:救起老妈,跟老婆一起S。我不敢苟同,难道老妈养你这么大就是为了让你去S么?本质上,这种回答是想站在一个中间立场,只是这样的结果不过是两边都站不到。更重要的是:作出这种回答的人,潜意识(稻草心表看到俺在这里班门弄斧-_-|||)里还是想丢下老妈,跟老婆一起的。估计这种人在实际情况下会先救老婆。

做人难啊。

反省

因为要处理一些XML的问题,所以上IBM的developerWorks查一些东西,结果看到这篇《实用数据绑定: 谁在使用这个东西,结果如何?》。其中有这么一段:

数据绑定不是时尚
对于任何新的、令人激动的 API,人们最常犯的一个错误就是将它与时尚混为一谈。这常常表现为两种典型谬误:

  • 没有认真地思考和测试就引入一种 API。
  • 所有可能的任务中都使用一种 API。

这些都是错误的观念,原因很多。比方说第一个问题,当出现一种新的、看来很有帮助的 API时,很多开发人员往往忽略添加新技术所需要的常规步骤。比如,没有经过漫长的讨论会、数以吨计的计划和大量的深思熟虑,您不会轻易地从 JDBC转移到 EJB。同理,兴致所至就匆匆甩掉 SAX 和 DOM 代码,取而代之以 JAXB 或者 JaxMe(或者Coins、Zeus、XMLBeans 等),也是极其不负责任的。

但是令人吃惊的是,很多开发人员恰恰就是这样做的。SAX编码很令人痛苦,回调不是很符合面向对象的思路,熟练掌握它又需要花很长的时间。DOM易于使用(尽管有时候存在一些不必要的麻烦,比如提取元素中的文本),但它可能变得很庞大,占用很多内存。但是,没有理由仅仅因为数据绑定是市面上最新的XML 相关技术就把其他 API扔掉。要花点时间考察新技术。阅读像本文这样的文章,演练示例代码,要谨慎从事。这样做可能慢一些,但是您可以省掉很多麻烦。

另一种诱惑是到处使用新技术。换句话说(使用数据绑定 API 这个具体的例子),不要假设您的代码每次处理 XML都要使用数据绑定。这种天真的、过于单纯的做法,几乎注定会在长期的运行中损害您的应用程序。比方说,如果拥有一些私有的 Perl脚本,能够很好地读取 XML,就没有必要增加转移到数据绑定的开销,这种情况下,没有必要舍弃原有的脚本。保留精力解决那些工作以及应该工作的任务。

其实把上面一段话里的XML数据绑定换成所有的时尚技术,都是基本成立的。

汗,我又犯了文中所说的错误了。-_-|||

我不应该到处使用这个说法

越南新娘

早上《第一时间》有一则新闻很有意思:

广州近年来洋媳妇增多,其中七成来自越南。

不禁让我想到以前在BBS上看过的两处图片:

无论战争的理由多么正义,受害的总是百姓。

然而几千年来,人类就是这样在战争中一步步走到了现在。

BTW:有必要补充一下,从图片上看,消息应该是来自台湾省,货币应以新台币计(目前汇率约为4.05,即1元人民币约折4.05元新台币)。

BTW2:回答abby,说明两个问题:第一、越南在过去几十年里的战乱导致了现在的经济落后;第二、台湾人娶媳妇的成本远高于二十万新台币。

BTW3:今天的新闻说明,广州娶媳妇的成本显然也不低。

BTW4:外电消息:At least 20 killed, 42 injured in central China ethnic clashes, 18 arrested

狐朋狗友赞

中午上UUZONE看了一下,几周没去,多了几个人。

我现在在UU的优友大多都是BLOG友。^O^

按本帮内部说法,咱们这些人都算是“狐朋狗友”,三五不时地就出来FB一下。

《庄子·山木》中说道:

夫以利合者,迫穷祸患害相弃也;以天属者,迫穷祸患害相收也。夫相收之与相弃亦远矣,且君子之交淡若水,小人之交甘若醴。

这段话是一个叫“子桑雽”的人用来教训孔夫子的。

RLK也说,朋友就要是能说知心话的,那才是真正的朋友。

很同意这些观点。

不过咱们都是普通人,不敢拿圣人的标准来要求自己。何况俺也从来不认为自己是什么君子,俺就是一个有RPWT的小人。^O^

而那种真朋友,是可遇而不可求的,如同伯牙与子期,而且这种朋友有一个足矣。再说这种所谓的真正友谊,也并不是人人都可以得到的。至少它只可能存在于近乎于圣人的真正君子之间,像俺这种小人是没希望了。:P

对于那些尚达不到君子标准的人所标榜的“友谊”,我一向是持怀疑态度的。与其恬着脸自称“真正朋友”,还不如坦白点说是狐朋狗友。

这种所谓的“友情”看过得太多了。没事的时候一切都好,一但有事–特别是有了利益冲突,HOHO……

一个朋友曾经跟他的一个好朋友合作一个项目,他负责和客户沟通,他朋友负责开发。结果后来他朋友的开发进度不能赶上,客户一怒之下要求他们退还预付款。但他的朋友却拒绝退还那几万元,他只能自己承担这笔损失。

那天他在MSN上跟我说:我和他可是十多年的朋友了,他怎么可以这样。

我只能安慰他:花几万元买个教训,认清一个人。

我也有一个十来年的朋友,他前年因为一个朋友摆了他一道,害他被公司辞退。他那个朋友我也认识,跟他也有很多年的交情(四年同学,毕业后还做过三年的同事)。

当时我跟他说的话比较极端,我说:你当他是金钱换不了的好朋友,人家不一定这么认为。这个世界上就没有真正的朋友。

他说:不会啊,至少你和XXX(我们的另一个朋友)肯定不会这样害我的。

我说:不要这样想。虽然在他这种情况下,我肯定不会害你,但是我不能保证在所有的情况下都不会。

此外,最常见的情况大概就是借钱了。朋友跟你借钱,如果你不借,这个朋友通常还可以继续;但如果你借了,很多情况下是朋友和钱都损失了。

伯牙和子期的故事会被千古传颂,幸好是因为钟子期早死。即便是竹林七贤,也照样会有嵇康与山涛绝交这样的反例。

对于俺这种小人说来,谈什么“真正的朋友”是一种奢望,还是狐朋狗友更适合俺。因为狐朋狗友之间没有什么利害关系,一起玩得快乐就是唯一的理由。和他们在一起,可以没有负担,生活轻松愉快。

我想大多数普通人更多的时候,需要的还是这样的狐朋狗友。大家可以一起吃吃喝喝,吹牛扯淡,分享快乐。可以说一些无伤大雅的小谎话,开一些小玩笑。

狐朋狗友,赞。

软件的版本更新检查实现

    还是在“PIA-MyPhotoGallery”中,为了能让使用者及时知道软件的更新版本发布,我增加了自动更新检查功能。鉴于这种功能具有很好的实用价值,所以写本文说明此功能的实现。

要实现更新检查,需要解决两个方面的问题:

1、通过Internet获取最新发布的版本号;
2、取得当前程序的版本,并与取得的最新版本相比较。

如果检查到有新版本发布,则打开下载页面(至于直接下载更新本文暂不讨论)。

对于第一个问题,最简单的解决办法就是在网站上发布新版本软件的同时,发布一个记录着版本号的文件。在软件进行版本检查时(比如程序启动时),通过Internet下载此文件,并读出最新的版本号。

注意:此方法仅适用于简单更新的情况,对于像杀毒软件的病毒库这样增量更新的情况,这种简单方法是不合适的,通常还需要有相应的服务端程序配合才行。

要通过Internet下载文件有很多方法,比如用WinINet API或现成的控件都可以。本文以Indy的TIdHTTP控件为例。

TIdHTTP控件的用法非常简单,但是直接使用它下载会有一个问题:程序会被阻塞着,直到文件被下载或连接超时(比如网络未连接)。所以必须将它放到线程中处理。

在PIA-MyPhotoGallery中,我用的代码如下:

//---------------------------------------------------------------------------//  Get new version threadclass TGetNewVersionThread : public TThread{private:AnsiString      FURL;TMFileVersion * FVer;protected:void __fastcall Execute( );public:__fastcall TGetNewVersionThread( AnsiString aURL ): TThread( true ), FURL( aURL ), FVer( new TMFileVersion( ) ){FreeOnTerminate = true;}__fastcall ~TGetNewVersionThread( ) { delete FVer; }__property TMFileVersion * Version  = { read=FVer };};//---------------------------------------------------------------------------//  TGetNewVersionThread//---------------------------------------------------------------------------void __fastcall TGetNewVersionThread::Execute( ){boost::scoped_ptr webConn( new TIdHTTP( NULL ) );boost::scoped_ptr ss( new TStringList( ) );try {ss->Text = webConn->Get( FURL );}catch ( ... ){ss->Text = "";}AnsiString s = ss->Values["piapg"];if ( s != "" )FVer->VerStr = s;}//---------------------------------------------------------------------------

这段代码很简单:创建一个线程,在线程里创建一个TIdHTTP实例,然后下载URL对应的文件,最后从中读出“piapg”的版本号。为了偷懒,我用了boost库里的smart pointer–scoped_ptr。

这个线程类的使用方法如下:

//---------------------------------------------------------------------------//  在程序启动时执行:if ( PIAPGCfg->AutoUpd )  //  如果选择了“检查更新”选项则执行检查{if ( SplashDlg )  //  如果有splash,则在其中显示提示文本{SplashDlg->labProgress->Caption = "正在检查新版本...";SplashDlg->labProgress->Refresh( );}//  创建检查新版本的线程TGetNewVersionThread * pThread = new TGetNewVersionThread( "http://mental.8gua.me/update.txt" );pThread->OnTerminate = GetNewVersionDone;pThread->Resume( );}//---------------------------------------------------------------------------//  版本文件下载完成或超时void __fastcall TMainForm::GetNewVersionDone(TObject * Sender){TGetNewVersionThread * pThread = dynamic_cast( Sender );boost::scoped_ptr fv( new TMFileVersion( ) );fv->GetVersionFromFile( Application->ExeName );  //  读取当前程序的版本if ( ( pThread->Version->Compare( fv.get( ) ) > 0 )  //  如果有新版本,则提示&& ( Application->MessageBox( "发现更新版本的程序,是否现在更新?","新版本检查", MB_YESNO | MB_ICONINFORMATION ) == IDYES ) ){ShellExecute( NULL, "open", "http://mental.8gua.me", NULL, NULL, SW_SHOW );PostQuitMessage( 0 );}}//---------------------------------------------------------------------------

此代码的功能详见其中的注释。

再来看第二个问题:程序版本的问题。

在上面的代码中,用到了一个类:TMFileVersion。这是我以前用DELPHI写的一个用于处理可执行文件版本号的类。实现代码如下:

TMFileVersion = classprivateFMajor   : Integer;FMinor   : Integer;FRelease : Integer;FBuild   : Integer;Function  GetVerStr : String;Procedure SetVerStr( aVerStr : String );publicconstructor Create;destructor Destroy; override;Procedure GetVersionFromFile( aFileName : String );Function  Compare( aVer : TMFileVersion ) : Integer;Property VerStr : String read GetVerStr write SetVerStr;End;{ TMFileVersion }//  initconstructor TMFileVersion.Create;BeginInherited;FMajor   := 0;FMinor   := 0;FRelease := 0;FBuild   := 0;End;destructor TMFileVersion.Destroy;BeginInherited;End;//  Get version info from a fileProcedure TMFileVersion.GetVersionFromFile( aFileName : String );TypePVS_FIXEDFILEINFO = ^VS_FIXEDFILEINFO;Varh : Cardinal;        // a handle, ignorenSize : Cardinal;    // version info sizepData : Pointer;     // version info datapffiData : PVS_FIXEDFILEINFO;  // fixed file info datanffiSize : Cardinal; // fixed file info sizeBeginFMajor   := 0;FMinor   := 0;FRelease := 0;FBuild   := 0;If ( FileExists( aFileName ) ) ThenFBuild := 1;nSize := GetFileVersionInfoSize( PChar( aFileName ), h );If ( nSize = 0 ) ThenExit;GetMem( pData, nSize );TryGetFileVersionInfo( PChar( aFileName ), h, nSize, pData );If ( VerQueryValue( pData, '', Pointer( pffiData ), nffiSize ) ) ThenBeginFMajor   := ( pffiData^.dwFileVersionMS ) SHR 16;FMinor   := ( pffiData^.dwFileVersionMS ) AND $FFFF;FRelease := ( pffiData^.dwFileVersionLS ) SHR 16;FBuild   := ( pffiData^.dwFileVersionLS ) AND $FFFF;End;FinallyFreeMem( pData );End;End;//  Compare two version infoFunction TMFileVersion.Compare( aVer : TMFileVersion ) : Integer;Varn1, n2 : Cardinal;Beginn1 := ( FMajor SHL 16 ) OR FMinor;With aVer Don2 := ( FMajor SHL 16 ) OR FMinor;If ( n1 > n2 ) ThenResult := 1Else If ( n1  n2 ) ThenResult := 1Else IF ( n1 < n2 ) ThenResult := -1ElseResult := 0;End;End;//  Get/Set property - VerStrFunction TMFileVersion.GetVerStr : String;BeginResult := Format( '%d,%.02d,%d,%.02d', [FMajor, FMinor, FRelease, FBuild] );End;Procedure TMFileVersion.SetVerStr( aVerStr : String );VarsTemp : TStrings;BeginFMajor   := 0;FMinor   := 0;FRelease := 0;FBuild   := 0;sTemp := TStringList.Create;TrysTemp.CommaText := aVerStr;TryFMajor   := StrToInt( sTemp.Strings[0] );FMinor   := StrToInt( sTemp.Strings[1] );FRelease := StrToInt( sTemp.Strings[2] );FBuild   := StrToInt( sTemp.Strings[3] );Except//  Do nothingEnd;FinallysTemp.Free;End;End;

解决了这两个问题,自动更新检查的功能也就解决了。

技术人员的出路

昨天vcbear留言说:

这年头大多数家伙都有外快的路子呀

可惜我是属于另外的一小部分。-_-|||

其实像我们这些S搞技术的,哪里有什么出息。唯一的希望也就只能是指望那一点S工资了。

外快倒也不是没有试过,二年前曾经跟一个同事给一个客户做过一个东东,结果累死累活做出来,那个客户又说项目取消什么之类,结果一分钱没拿到。气S,早知道先拿点订金也不至于白干。

至于稿费,也就上个月《程序员》用了我的一篇文章,稿费现在还没拿到,不过估计也没多少,在《程序员》杂志社投稿须知说得很明白:

原创稿件稿费一般为每千字 80-150 元。

远不能跟别人在时尚杂志上发东西的稿费相比。

写技术书的事,我也干过。大概也是前年的时候,掺和到一个所谓的工作室里,写了一本跟DELPHI有关的书。基本上技术书的特点就是:

书的质量与作者人数成反比。

所以这本书也就没有卖出多少,加上那么点稿费还要那么多人分,最后我拿到的钱也就够几个朋友吃一顿的。

所以还是死了这份心,保住那份S工资就好。

BTW:下午出去逛了一下,买了几张碟。现在真是越来越先进了,连续剧都用MPEG4或RMVB压缩后,一张DVD可以装十几集,方便啊。

BTW2:新的烦恼是:什么时候才能把这几部共计一百多小时的连续剧看完呢?

空白

本来从去年12月开始,我一直保持着在CSDN个人专栏每月至少一文的。但是,这个十月是一个空白。

一方面是因为公司的SAP这个月来问题多多,不但自己搞得焦头烂额,连顾问公司的一帮子顾问也都快被搞到崩溃。-_-|||

前几周有一个顾问还把程序给改错了,把偶们的数据都搞乱了,虽然现在俺已经把程序改回来了(还好他有注释说他改了些什么),可是乱的数据已经没办法了,那帮出纳也快崩溃了。

不过最主要的原因还是因为下了班还要给朋友写一个程序,结果这一个月也就没有研究什么值得一说的技术,自然也就没有什么可写的了。

不过空白总是可耻的,下个月一定要补上,至少两篇。^O^

周末

可惜明天还要上班。

这真是BT的一周,自打周一开始,本帮就在mblogger上进行了几轮大规模的BT活动。帮里帮外的bloggers都有波及。比如可怜的cynthia、gaolun和reallike。

被Applet折磨得够呛。好不容易搞定交货,对方说在老版本的JRE下跑不动,试了半天才发现老版本的JRE要求Applet和HTML在同一个URL下。麻烦撩~~~~~

BTW:央行开始加息了~~

BTW2:刚才令狐发来一个有意思的文章:《好公民不助长非法拷贝 — 请停止散布 .doc 档》,偶用FoxMail把它转成了简体版。^O^
虽然用FoxMail转起来略有一点麻烦,但至少比WORD强的一点就是:它不会自作主张。而任何经WORD处理过的标准的HTML,在保存后都会被转成MS特有的非标准HTML。

每天一日

今天是“全国男性健康日”。

伟人说:“电脑要从娃娃抓起。”

看了这则新闻:《学院书记下任务 舞蹈专业女生停课给领导陪舞》,恐怕就要被BT成:“男性健康要从领导抓起”了。

上海北郊环高速天梁断塌事故据说已经被确定为操作不当造成,祈祷领导们这次说的是真话–看吧,说谎说多了就是这样让人不可信任,R老师说得真对。

河南大平煤矿瓦斯爆炸事故,迄今已有129名矿工死亡,其他19人生还的可能性越来越小

天气预报显示,最近以来,华中华南持续干旱,大部分水库都停止发电,以保证饮用水和灌溉的需要,广西部分水库甚至已经见底。

枯水季节的到来,同时也是冬季用电高峰。烧煤的火电将成为供电的主力。然而如新华网所说:带血的煤不挖也罢。

从失语说到IT人的说话方式

今天在稻草心那里看到《失语》,说到了中英文混用的问题。稻草心是因为在国外用英文比用中文多得多,时间长了难免失语。可是在国内–特别是IT业–却有很多人故意如此,五年前还在金山卓越混的知名写手猛小蛇就写过一篇文章,批判过这种事。

刚好昨天晚上我在等待程序编译的时间里,看了几页《彼德原理》(讲的是在组织中,个人的晋升极限问题,即每个人都将最终被晋升到他不能胜任的位置上),在其中的第十一章:《晋升极限的非医学指标》中说到一种情况:

不正常的说话习惯。

其中就有一条:

使听者莫测高深。

好好的中文不说,偏要夹一点英文。专业术语也就罢了,毕竟电脑这玩意儿是洋人发明的,他们顺带发明的一些词,暂时没有准确或统一的中文译法,用原文还有点道理。问题是偏偏夹的还是一些日常用语。sigh

其实这就是一种不能胜任的表现。

这样说来,俺昨天的POST也是一种不能胜任的表现。-_-|||

为了跟RLK斗法,俺大量使用了一些故弄玄虚的术语,以制造莫测高深的形象。

结论是俺不能胜任跟RLK斗法,故到此为止。

其实说了半天,俺只是想为自己英文不好作一个辩护而已。-_-|||

关于此事的典故见俺在帮主那的关于“彩旗亲戚管理”系统的回复。

再汗。-_-|||

补水ing