怪怪 | Nothing, Everything

"有过一个发疯的时刻,有感觉的钢琴以为它是世界上仅有的一架钢琴,宇宙的全部和谐都发生在它身上." - 狄德罗
随笔 - 94, 文章 - 3, 评论 - 1886, 引用 - 42
数据加载中……

2008年2月27日

喧嚣

过去两到三个月,一些总结是有的, 但很难说有很大进步,这是不得不意识到的。

 

从状态上来说:


1. 基本放弃了自我管理。

 

2. 目标对我来说似乎也没有威慑力了,毫无紧迫感。

 

3. 不能说毫无意义, 但确实一点也不充实。

 

从技术上来说:

 

1. 除了少数想法算一些整理, 没有悟到更多东西。

 

2. 一些地方反而过于热衷于言语, 而放弃了本质。

 

比如关于面向对象和其它范式的语言; 最早我就明白Anders说的“对象说到底不也是语法糖吗?”、“delegate就是函数式的全部了”, 但是实际上在这方面的思考并没有新的进展, 也包括对泛型、模板、元编程的体会上,还差那么一点点。

 

而对于“语法糖”这个概念, 不要光停留在表面理解, 类似于面向对象的非本质性, 对我个人来说,已经无需再讨论。相反,delegate并没有把C#变成强大的函数式语言,恐怕在于类型系统的配合度还不够,所以delegate在C#中就很容易表现的像个语法糖。作为具体的议题,后者是一个还存在模糊的地方,而我缺乏深思。

 

关键在于, 哪些东西不是语法糖; 这个地方我没有好好的把握住。 抓住这一点, 在设计和实现时就不会被迷花了眼, 在语言的学习和设想上, 也能更加的击中要害。 再重复一遍,哪些东西不是语法糖?界限在哪里?

 

实际的产品开发,也要重新进入轨道。最近缺乏实践的带动, 而在此之前, 对Web框架的理解,对各种编程范式的理解, 从经验上来说,都是被实践带动的。所以重新回到根本,即便对于高一层次的研究, 也是必要的了。

posted @ 2008-07-23 06:17 怪怪 阅读(262) | 评论 (6)编辑

资料收集

基础资料:

 

用来增加背景知识的资料:

 Why Gnutella Can't Scale. No, Really. 

(待更新)

 

可能需要了解的资料:

 

非结构化:


“Mobile Agent based Method”,这个想法初步感觉有点爽,和我的想法有相似性,找点文章来看。

 

Cache Method”的当前样例中, 有啥有新意的细节可以挖掘没有?

 

结构化:

(待更新)

 

实用资料:

 (待更新,这部分恐怕比较难找,可能还是得看代码。)

 

初步的想法, 实际上P2P网络的问题, 可以集中于两点:

 

1. 检索。

 

2. 有效。

 

关于1, 结构化的方法, 一般都是将内容与某一节点做一个映射, 信息提供者向这个节点汇报, 而信息查询者从这个节点获取。 同时, 这个节点的存在和同一,是通过“我们处于同一世界(物理上、时间刻度上)”这一事实来保证的。 除了实现细节的各种调整与优化之外,是不是真的没有改进的余地了?或者说,除了上述事实, 还有什么其它可利用的条件呢?

 

关于2, 分布式计算看似高端,其实反而可以含糊,因为只要不涉及远端计算机提供信息, 尚可以本地计算, 最终对一个可分解的计算来说, 仅仅是计算时间的问题; 信息传输要求稍微高一点,因为只要损失超过一定程度, 整个信息就是无用的; 而连续性播放则是比较难,但目前可以通过特殊处理解决。当这几者混合应用时, 问题可能会变得更加复杂一些: 多个部分的不同安排,可能导致可靠性在时间上的变化。

posted @ 2008-07-21 23:36 怪怪 阅读(397) | 评论 (1)编辑

交朋友的学问

交朋友这个事情是这样的, 咱们自己确实得努力, 否则有点水平的就不会倾向于和咱们建立关系。 不是别人骄傲, 而是如果交一大堆朋友, 用于交流的时间又有限, 到时候反而不知如何处理,得罪哪一个也行不是。

过去我玩Q3, 如果我在服务器里打的表现不错, 很多就要加我; 开始我是不会拒绝的, 但是QQ上人多到一定地步, 我开始没法弄; 最后即使我加了别人, 也不代表我会和他说话, 因为我必须隐身而且装的跟真的不在似的, 否则就别干别的了。但是我也有类似于全国前三那样的朋友, 为什么呢? 虽然我打不过他, 但是我有一些特色, 再练习中能够帮助他们提高。 这个开始我也不懂, 后来其中一人写文章和聊天时提到,我是他提高的三个阶段的最后一块踏脚石, 比如我的身法非常好,我才逐渐明白。

交朋友还有一些其他学问, 比如有一些人, 他即使不认识你, 你也可以把他当朋友。 比如对于我来说,这些人就是像Martin Fowler这一批。 当你把他们当作对话的对象, 你自然会提升的很快。 基本上, 在自己感兴趣的领域, 挑这么几个朋友, 所有你感兴趣的话题, 你都可以和他交流一阵子,Email吗? 不是, 就是很简单的他写过什么文章, 说过什么我怎么想; 我有什么看法,在同样的问题上, 他又怎么看。 在水平还比较初级的时候, 这种交流可以持续很长时间而且够用;真正的朋友能起的作用不也就是这些吗?

但是不要把那些真正高山仰止的人物当朋友, 因为说实在的, 没到一个级别, 根本无法做出这种交流。如果硬要上, 这样完全单方面的信息流, 会整个的毁了我们, 最后让我们彻底成为他的手下败将: 没有自己的想法, 只知道重复。 当然, 也许Fowler是我的朋友, 但还不是你的。 也许Anders已经是你的朋友了, 但还不是我的。 这完全取决于一个人和“目标朋友”的相对差距; 对这种人, 我们要承认他们是你我绝对意义上的老师, 但永远不要忘记一句话, 吾爱吾师, 但吾更爱真理。 总有一天, 老师变成了朋友, 虽然这不代表我们到了他那个级别, 但也有所小成了。

配合上面的“虚交”, 得到一些提高以后, 获得一些真正有联系的朋友, 也就是很快的事情。 因为人家会发现, 对他感兴趣的领域, 哪怕你还不是太够格, 但是也有一些自己的理解。 这样这些真朋友, 会愿意传授给我们他们的东西, 以期我们进步的更快一些, 也能回报给他们一些信息; 甚至我们暂时还不能给出回报也是有益的: 当他给你开讲的时候, 他也就获得了一次整理自己思路的机会。 但是, 绝对没人会愿意给一个完全不入门的人讲上好几个小时, 除非他打算去学校当个老师。

记住,最好的朋友是实力比我们高出一截, 但不至于太离谱的; 这包括真朋友和YY出来的朋友。前者一般是在一个数量级以内的,否则有联系方式也没用;后者的水平可以和你差距一个半数量级, 但不能更多了。在这之外, 交水平比自己低的朋友也是有益的, 标准基本上就是把上面的反过来; 但这一般是下意识就能做出的判断, 就不多说了。

posted @ 2008-07-18 14:03 怪怪 阅读(765) | 评论 (11)编辑

不需要强类型, 需要强测试?

     摘要: 这是Joel的观点, 据说, Bob大叔也是这个观点。 他们认为编译器的检查, 实际上就是编译期的测试。 而且他俩, 据说都达到了“测试成瘾”的境界。这就是说,他们抛弃过去对检查、尤其是静态检查的信仰。

Joel本人也曾一天到晚的思考, 是不是有一个最佳的方法,可以尽量少的付出代价, 尽量多的得到不同做法的优点; 不过他、Fowler、Robert Martin, 似乎已经都放弃了, 他们放弃的对吗?  阅读全文

posted @ 2008-07-18 06:19 怪怪 阅读(2070) | 评论 (21)编辑

一些待解的疑问

想了想, 还真不知道拿什么题目起头。 这样, 从以前的文章开始好了。

为什么OO是有本质缺陷的?


这篇文章中的疑问首先有这么一点: 静态语言中,我们如何能在改变一个系统内部接口的时候(注意, 不是对外发布的, 所以没有不能更改的问题), 只更改一处就解决问题? 比如最简单的, 一个类, 有Name属性, 是string的, 它对应某一个数据文件里的类似于表中一列的信息。 改变数据文件的结构,新添加了一个叫做Description的记录信息, 一个内部实体也增加了这个属性,我如何做到不修改从数据文件中读取, 和写入数据文件的代码呢?

毕竟, 这两个属性对这个数据文件的读写, 是没有什么差别的。举一个对比的例子, 在C++中, 我可以这样:

namespace fields
{
    
struct name;
    
struct age;
    
struct code;
}


typedef map
<fusion::pair<fields::name, std::string>, fusion::pair<fields::age, int>, fusion::pair<fields::code, char> > person;

使用时,我们这样使用:

person a_person;
at_key
<name>(a_person) = s;
at_key
<age>(a_person) = i;
at_key
<code>(a_person) = ch;

事实上, 这是使用fusion,稍微更改一下形式, 就可以变成这样: a_person.p<name>, a_person.p<age>。如果碰见变化, 修改一下typedef即可。 而我操作person的代码,只要其本身的逻辑没有变化,就可以做到一字不改; 因为我可以通过获取map中所包含的类型定义携带的信息, 直接写一个统一化的过程, 进行所有操作。 而如果使用OO, 第一个可以想象的就是, 每一个倒腾数据的逻辑, 无论是从哪儿到哪儿, 我都得加上对该属性的操作。

这个最大的好处是,只要在本质上是相同的过程, 我们只用写一遍。 另一个好处是, 我们同时具有静态语言的全部优势: 比如没有定义和包含description的时候, 无论你是at_key<description>,还是a_person.p<description>,根本就不会通过, 这样在非常大量的这种工作, 比起Dictionary和动态语言, 我们就可以避免大量的失误。

我想, 这个问题不能简单的用“很少有人用”来回答,因为它是结果。 首先它是方便的,而且方法名、属性名这种给人使用的死标记没有的缺陷它也没有。  那么我认为,没人用更多的仅仅是因为, C++和另外那些支持这种非OO范式的静态语言,其它地方太烂,是首先否定了语言上的选择, 所以也就没人在实体上使用这种设计和实现的方式。

当然使用Dictionary就痛快多了, 不过强类型带来的保障没了,这是不是缺陷呢?还可以使用反射完成相同的功能, 然后付出性能, 在我看来,这个性能就是缺陷的证明; 比如: 数据源是数据库, 那么有的ORM就用反射完成类似的工作, 但ORM的存在,反而证明了需求的存在。而且在ORM覆盖范围以外的数据复制和转移呢? 性能问题, 我们可以通过Emit来解决, 但Emit不是适合于所有使用情景; 而且, 我们就必须编写和调试大量的Emit代码, 额外的设施的使用和多付出的工作量, 也是缺陷的证明之一。

毕竟, 这些信息本来就是运行前已知的, 而且他们是有规律的, 也就是可以通过某种形式在运行前处理的, 同时可以通过合理表达自动化的。某人嘴里的“孟老头”对这个事情有他自己的理解, 现在就看某人的啦: 这是不是OO的缺陷?

posted @ 2008-07-17 12:16 怪怪 阅读(141) | 评论 (18)编辑

我来当个小人吧, To 关心博客园精华集的人、包包和搅风搅雨的人

     摘要: 现在我们所有人, 包括dudu、编委会成员、 出版社提供参考意见的同仁、 广大园子里的朋友, 首先要确定的一件事就是, 这些书应该是什么形式的? 也许甚至不同的分册不同的形式, 一切从实际出发。

除此之外,再无其它和人相关的冲突和矛盾。 再有人就这次具体事件, 针对某一个人或者牵扯进来的其它主体, 那就是找抽了。  阅读全文

posted @ 2008-07-17 03:34 怪怪 阅读(2970) | 评论 (138)编辑

两个过去的心得, 外加一个回帖整理

     摘要: 写程序、做设计是一个边学边干的活计,有一个著名的调侃, 就是如果程序员盖的房子, 你敢住吗?

广泛的掌握面向对象的手法, 但不要因为自己学了什么就给自己下套子, 那和屁股决定脑袋差不多。 学的这些东西是备用的, 大环境让我们必然能够用得上。 与此同时, 根据需求出发, 当自己有强烈的感觉, 某个学习过的东西, 能够解决当下的问题时, 再去试着应用。有的剑, 出鞘越少越好。

散文一篇, 不喜勿进。  阅读全文

posted @ 2008-07-15 05:56 怪怪 阅读(2291) | 评论 (22)编辑

WebResource备忘

已经不知道多少次掉进这个坑了....,一段时间不用就忘, 每次都得耽误半个小时。 这一方面说明, 这个功能的文档配合的不够好; 另一方面,真应了那句话,好记星不如烂笔头。

这就是: 资源文件, 如果放到目录里, 编译以后会被加上目录名....,这其实是必然的: 否则不同目录的同名文件如何处理?写到这,又推翻记性或者笔头的用处了。 因为这个事情太简单, 我反而没有琢磨这么基本的一个道理, 导致不能够在“哟?怎么回事”以后马上判断出是什么情况。不过这事也难说,也许我已经按这个思路想过, 不过还是没记住。 所以还是应该有做笔记的习惯。

顺便说点其它的。 Tag和Category这两个东西, 按理说本质差不多, 但这是一个朝三暮四的故事。 关键是你鼓励用户怎么做。

很多人认为Tag是随意的、即兴的,所以是私人的。 其实正好相反。 Tag其形式鼓励用户随便填写几个相关的短词,结果正是因为这样, 反而造成了不同的人写下的词可能是共同的, 于是这就变成了一个社区的、公开的、交流的、 把人和人、内容和内容相关到一起的公众的东西。仔细观察互联网用户,就会发现, 那些更加懂得如何*在互联网上*交流的同志, 会更多的用Tag,而且用的很准; 而比较嫩或者比较老的网民, 就会瞎写或者不写; 但即使瞎写, 也能增进和其它内容制造源的联系。

而Category鼓励用户仔细的去设置分类, 所以反而会突出人的个性。 比如同样对旅游这一件事,对A意味着很多内容, 对B也意味着很多内容, 哪怕这些内容大部分是重叠的, 仍然会因为不同的部分, 产生不同的Category表示方式, 结果这就成了两个分类。 而整个社区如果设置了分类,也仅仅是从网站出发,属于网站的个性为网站本身服务。假设一个网站有三种分类方式: 个人Category、全站Category、Tag, 这看起来完美, 但是会让用户最后哪个都不填, 因为太麻烦了。

当然, 真正实现Category和Tag的时候, 可以让它们产生极大的不同, 但即便是设计者, 实际上也是以“如何给用户一个导向”为导向的。 如果Tag本身能够组织, 形成图, 其实是一个非常有意义的事情, 不仅仅是相关性, 而是各种可能的关系都可以形成组织。 Category本身也可以极其强大, 而不仅仅是树状的模式。

实际上,一般的设计者区分两者的手段, 就是根据预期的导向,让其中之一在某些方面较弱, 而另一个在其它的方面较弱。 如果两个都强大到极端, 那么可以肯定功能是相似的。 但真正想清楚这些问题, 就会发现没有必要通过故意的功能性差异化去在系统内部作出区分。

只是在这个“两个都达到最强”的状态(或者可能是干脆基于一套内部模型的状态),反而要加倍注意用户导向的问题,这个时候可以通过界面、提示、交互方式等表面的东西来做出区分。 否则用户将会觉得迷惑和繁琐, 以至于放弃这些功能, 这对社区的组织者和内容发布者,都是一个损失。

还有点其它的本来想写, 不过还是别浪费时间了。 STOP。

posted @ 2008-07-12 09:45 怪怪 阅读(326) | 评论 (0)编辑

年轻人的未来在哪里?


posted @ 2008-07-10 19:32 怪怪 阅读(174) | 评论 (7)编辑

有一点我不得不思考的

有空了解一下OWL,看看是不是能给我的一些想法新的启发。初步的看, 似乎有点掺杂着一些不纯洁的概念。不过,Ontology的概念还是很明确的:

引用本體論譯自英文ontology,又譯存在論或是論,它是形上學的一個基本分支,英語詞ontology是來源於希臘語單詞ον(存在)和λ?γο?(學問)的組合。ontology主要探討存在的本身,即一切現實事物的基本特徵。

有的哲學家,如柏拉圖學派認為:任何一個名詞都對應著一個實際存在;另外一些哲學家則主張有一些名詞並不代表存在的實體,而只代表一種集合的概念,包括事 物或事件,也有抽象的,由人類思維產生的事物。例如「社團」就代表一群具有同一性質的人組成的集合;「幾何」就代表一種特殊知識的集合等。

ontology就是「研究到底哪些名詞代表真實的存在實體,哪些名詞只是代表一種概念」。所以ontology成為某些哲學分支的基礎。近年來,人工智 慧及資訊技術相關領域的學者也開始將本體論的觀念用在知識表達上,即藉由本體論中的基本元素:概念及概念間的關連,作為描述真實世界的知識模型。針對此一趨勢,W3C組織也開始定義了許多Ontology的相關語言,如RDF、DAML+OIL、OWL等。

为了统一性, 如果实现一门用于描述的语言, 可以忽略一个名词都对应一个实际存在这一分支, 而是加入一层, 认为每一个名词都对应满足一组条件的集合。 这样就和面向对象彻底分道扬镳了: 类也好什么也好, 只是一个方便我们组织和使用的别名, 没有更多的意义; 而每一个实体都是被用各种特征织起来的。 同时,面向对象中接口这样的鸡肋概念也可以去除, 而只检测一个实体是否满足条件。 这样, 静态语言的检查可以得以保留, 同时还可以延伸出自动推导等更高级的组织方式。

这也是我目前和脑袋的分歧所在, 脑袋更看重可行性, 认为借助CLR和保证与CLR上其它语言的兼容是必要的做法; 鉴于底层模型和其它语言接口要求的限制,这样就没有办法实现类似于C++模板的功能。 而我虽然更菜一些, 但是反而更“不切实际”,希望在这上面有所突破。 到底应该如何选择呢? 有没有变通的做法呢?



另外,早期和我有交流的, 还有我那失败团队里的家伙们应该知道,其实我的Web框架本身、框架想要支持的产品和当初我设计的商业模式, 基本上和后来从FaceBook开始的这一大堆平台战略相类似。 现在说啥都没劲了。 我需要考虑的一个问题是,到底是因为我进度慢, 还是这个事情, 小团队根本做不了? 说实话, 我不太相信后者; 我自己的分析是我的自我管理能力和执行力还需要锻炼, 对集中式应用缺乏应有的信念、对如何进入市场心存疑虑。

另一个具体的延误是,在Web框架到产品这一层, 对界面组装的灵活性和行为划分的严格性要求太高,而我一直没找到让我心满意足的设定,导致一直迟疑不决。从DNN到Weebly到现在的这帮家伙,人家更 NB的组织都知道先弄个能转的东西放出去再说, 我是不是太机械和2B了? 这个地方我很确定不是因为自己的技术无法支撑, 所以应该集中反思产品策略问题,“黄金圣斗士不会被同一招数击中两次”, 我想我需要谨慎的思考。当然,也不能一概否定: 如果不是这种性格, 我也不可能不断的获得很多思考和提高; 所以主要是,在哪儿较真, 较多少真的问题。



我到底是不是一个真正的技术人?

我想成为一个顶尖的技术人, 但:

1.这个想法, 是真实的吗?

2.我相当的能说废话, 一个说废话的人, 其性格适合做一个技术人吗?

3.我没有专精, 而是每一个接触的方面, 都达到比第一流差的那个水平, 这是一个好事还是坏事?

希望跟我有接触的朋友们, 帮我观察一下, 并提出建议, 越难听越好。

posted @ 2008-07-08 01:55 怪怪 阅读(790) | 评论 (4)编辑

昨天到今天也很高兴

     摘要: 作为技术人员, 我要把这本非技术的书, 放到SICP之前;作为德鲁克的崇拜者,我要把这本书放在《卓有成效的管理者》之前来;作为佛洛伊德、荣格的初步接触者,我要把这本书放在《梦的解析》、《现代灵魂的自我拯救》之前;作为巴尔扎克、陀思妥耶夫斯基的忠实读者, 我要把这本书放在他俩的一切作品之前;我甚至会把这本书放到老庄之前: 是的,这只是一本相当业余的小书,不乏一些不求甚解的成分,甚至也稍嫌肤浅且有点八卦; 但凡是围绕人的著作,没有一本对于一个像我这样的平凡人而言, 更加有实用价值了。

作为一篇全是八卦的博客, 我认为我有责任作为这本小书的枪手,把它推到首页,只希望其它人也能分享这份喜悦。 也许它并非完全和技术圈子是无关的: 很多兄弟对从业的感受和迷惑, 说不准能从这本书中找到答案。 这本书的名字叫做《遇见未知的自己》。  阅读全文

posted @ 2008-07-07 08:04 怪怪 阅读(3158) | 评论 (50)编辑

资料

http://en.wikipedia.org/wiki/Comparison_of_BitTorrent_software

http://en.wikipedia.org/wiki/Comparison_of_eDonkey_software

posted @ 2008-07-05 03:39 怪怪 阅读(1265) | 评论 (1)编辑

妈的

最近的一些感受。

首先,deerchao说的是对的, Community Server 2008要比2.1强太多了, 当然, 对于我来说还是不够好; 不过, 既然我自己没有能力拿出一个若干万行、并且好多人都在用的产品, 我就别他妈的JJWW了。 这件事的一个想法是: 有谁愿意提炼和修改Community Server 2008的,我愿意参与,我的想法是:

1.继续精简和重构。
2.改进对中文的支持。
3.重新开源之。

为了目标1和3,一些代码不妨重写。 这样的产品, 难说什么专利, 只要重构的程度跨过某一水平线, 版权不是什么问题。

第二件事, 我为了试一个软件是否存在时间过期, 调整了系统时间, 重启前也忘了改回来; 结果Windows 2008让我激活, 在这里提醒一下那些像我一样靠240天评估期使用非盗版Windows的同志。

第三件事, 重装的时候, 忘记旧软件应该先装, 比如Sql Server 2005应该在Visual Studio 2008之前。 有时候一些最简单的事情也会犯错, 所以细心和把细心的结果形成习惯,还是必要的。另外, 了解了一下Installer安装组件和Hotfix的思路, 发现一些问题还真是难处理;初步感觉,其实我们自己设计真正的软件时,也可能会碰见类似的问题,看看能不能沉淀一下,变成可以触发的联想的知识和经验。

第四件事, 我决心调整重点, 把Web框架作为次要工作了,我现在就必须开始P2P的研究。 从06年年底开始到现在, 一直没进入真正的产品阶段, 我想这绝不光光是因为我懒, 而是存在深层次的问题。 分布式、非集中的网络,才是我的信仰;我是不是真的愿意做Web框架,还是因为从事过一些Web开发就习惯性的走到这个道路上,我没法去分析清楚。

但是我自认对Web开发的方方面面,有一些体会还是很准确的。我希望我的实验成果还能为别人发挥一些作用,所以我还会把它当作一个副业继续。也许这样,心态反而会变好,作为一个副业,效率比这1年半还高也不是不可能的事情。

关键是了解自己,管理自己,这才是重中之重。

Update:
多加一件事, ATI的程序员不是人。 就是因为有了这样的程序员, 一般群众对.NET的印象就越来越坏。

posted @ 2008-07-02 07:53 怪怪 阅读(2220) | 评论 (9)编辑

最近回帖整理:

原帖,针对第四点:

看看客户所说的话, 能不能整理为一个自然语言的子集:与业务相关的小语言,并形式化。 实现过程可以三步走:

1. 对需要变化的业务规则建立统一的模型。

2. 使用解释器模式配合配置文件来表达小语言,应对变化。

3. 当2变得复杂和难于掌握, 考虑实现一门业务小语言, 难度较深。

纸上谈兵, 没机会实战过, 而且我估计这个成本对于承接项目的公司恐怕难于接受; 除非在市场上有多家公司需要这种东西, 这样算是预支成本吧。

对于一般技术人员, 可能认为难度在于实现小语言。 其实最难的一部分是如何将业务规则及其变化归纳为一个可接受的表达形式。

posted @ 2008-07-01 06:17 怪怪 阅读(2224) | 评论 (4)编辑

怪怪论三国:到底该关注些什么

发现博客园对三国感兴趣的人很多,不过关注点似乎和我都有所不同。要是让我看,三国时期只有一个英雄那就是曹操,除此之外就只剩下层次高低不等的流氓及其团伙一干人等。说实话,曹操身上最大的一个弱点,或许就体现在“天下英雄唯使君与曹尔”这句话中了,这说明他的精神境界中还有一些和刘备一样低劣的东西,如果曹魏最终的衰亡真有曹操自己的因素的话,恐怕就在这里了。

有人说三国志中曹操传比别人长比别人详细, 是因为作者以魏为正统, 个人不以为然: 比较一下职业生涯中,在动作的大小和频率方面,刘孙与曹操之间存在的不可弥补的差距, 就可以知道刘备、诸葛亮等作为与日月争辉的星星,不过尔尔。 有兴趣的, 以对于孙刘而言是大动作的粒度, 对曹操阵营的动作做一个列表, 比较一下三者的长短, 再配合时间轴一看, 这些都一清二楚。 这个故事本来一点也不复杂, 只是后面那些只知道拿三国吃饭的学者们把它弄复杂了。

很多人关注三国,着眼于做人,比如曹操所谓的权谋, 这实际上只是旁枝末节。 曹操此人身上所蕴含的巨大而无可匹敌的能量,才是真正无法忽视的根源;即使他做事方法变一个样,结果也不会逆转。 曹魏的命运, 也许可称的上“天亡我, 非战之罪”。 这个问题我没有足够的知识与能力关注,只说两点: 曹虽然起家于官宦家庭, 但其势并不比陈胜吴广项羽刘邦更好;客观历史环境所导致,那个时代的创业者比任何一个其他时代需要做都要多,以他的寿命是无法完成的。

要说做人,我们真正要看到的是,曹操做事情的节奏;我们还不能忽视的是, 无论作为政治家、军事家、社会活动家、文学艺术家,曹操的杰出成就的总和,可以说在中国历史上是数一数二的。 就像数学家标榜的“人类心智的荣耀”,和所有那些取得成功的人所真正留下的宝贵财富别无二致的,他的一生展示了一个人可以达到的极限有多远。 有些人可能认为,像文学艺术这样的东西,和曹操的成功失败没有必然联系,但事实上,正是曹操的内涵决定了他是一个什么样的人。

那些只注意权谋、机巧的人,是不可能走上和刘邦、曹操这样的人一样的道路的。 简单地说,像他们这样的人,好比上了发条的机器,没有停止的时候;而且他们通过训练,可以让动力衰竭的速度,控制在一定的范围内。当一个人在一条道路上,相对时间相展开到绝对时间上比其它人多好几倍,他注定要比所有人强。 这才是历史给我们上的第一课,没有这一课,纯粹的认为(类似的)老毛之所以是大家的头儿,是通读了二十四史或有什么其他杰出才干,是毫无意义的。

孙武告诉我们说,以正合、以奇胜,这已充分说明了孰在前、孰在后。 把周遭的人和事情想的特别复杂,并且和历史对照,在我们有足够的“正”之前,未必是什么好事。作为我们文化历史中的重要组成部分,对刘关张和诸葛亮的褒扬,对曹操“奇”的一部分的过多关注,过去几百年来对我们的民族是贻害甚巨的;这种传统掩盖了最重要的东西:如果一个人没有掌握真正的内在因素,就沉迷和训练自己什么做人、领导的艺术,哪怕就是极端的小人也不能成为合格且成功的大坏蛋。

我们首先要注意的是那些不平凡的人身上积极向上和光辉的一面,他们告诉我们一个人通过自身的努力可以换来什么样的奇迹,这才是属于全人类的骄傲。虽然作为一个普通人,拿我们和BT相比似乎没有什么意义 -- 但我认为,这些才是每一个想改善自己,取得更大成就的人所要关心和学习的; 至少借由这种鼓励,我们可以去尝试突破自己, 这才是真正的榜样的力量。

posted @ 2008-06-29 08:35 怪怪 阅读(3948) | 评论 (49)编辑

闲逛, 看见这么一句话

很随机的不小心进入网上一个不知名的博客,其随笔里提到的,他似乎是个经济学的研究生什么的。

此人说道我站在马克思的“生产力决定生产关系,生产关系制约生产力的发展”的观点上去解释组织的起源,而非交易费用节约的角度,交易费用节约只是组织的功能,拿功能来解释起源就犯了“功能主义”的错误。

嗯嗯,有意思。很显然我没必要去和他比他们领域内的知识和能力啦,不过还是有些额外的思考。

过去我也是信马克思的,而且,“生产力决定生产关系,生产关系制约生产力的发展",这一简单基本的观点,我现在也在用。但是随着我自己的世界观的形成,我似乎开始有了变化。
使用新的世界观,就不会简单的给不同的角度扣上各种大帽子。从交易费用节约的角度上看,真的是所谓的功能主义吗?即使是,功能主义背后所隐藏的东西,会不会比马克思的观点更朴素更基本呢?

有一个防雷的经验,就是说,如果在雷电击中你的那一刻,你抬起的是左脚,你比较不容易被电死。说实话,我是一个驽钝的人,想了好一会儿才明白为什么:电流想要流入地面,必须从右脚过去,这就有一定概率让电流避开心脏了。但我们不要忘记另一个事实,雷电是击穿空气打到你身上的,那为什么它不击穿你左脚和地面之间的空气呢?

这个道理非常简单,上过初中就学过,电流倾向于从电阻更小的地方通过;由于空气的电阻大大大与我们身体的电阻,它不会去选择击穿空气。我这些描述,细究的话,错误百出,而且很不严谨的拿电流当作了主语;但它在大体上是那么回事。这体现了一个非常基本的规律,就是能量最小耗费的原则;同样,作为更适合当主语的人,如果在获取的信息足够的情况下,我们也会执行最省事的一个方案。

我们可以考虑,如果人类和电流没有这种共同性,恐怕在物竞天择的自然界中,我们早就被淘汰了。所以我们可以认为这是宇宙本身的意思,它告诉电流那么做,也告诉我们该怎么做。我们并不需要高深的哲学和复杂的科学,只要愿意去多了解一些,就可以很不严谨的建立起一套正确概率还算不错的指导方针。

马克思的观点在这里,其实恰恰不是原则,而是结果。
我们把“组织”等同于某一种生产关系, 这种生产关系之所以产生,必须符合来自宇宙的指导,这些指导之一显然就包括能量最小耗费原则:我们可以想象,一些领域内活动(不止交易),在某一生产力和其它可能存在的条件下,一种生产关系会比另外一种生产关系更加节约,那么节约的那种生产关系就会屏雀中选。

我这样的说法,和单纯的交易费用节约又有很大不同,但是仍然可能是功能主义的:因为实际上是“节约”这一功能在前,生产关系的起源在后;是为了节约才有组织,而不是有了组织才节约;如果浪费是组织必然行使的功能,组织这种生产关系还能有起源吗?这也就是亚里士多德所说的目的因。另外,我对它的使用本身,就符合了能量最小耗费原则:针对我所需要掌握的程度,这种解释方式可以让我使用更少的能量去琢磨它。

马克思的总结中,还有一些其它因素,比如生产力,为什么生产力会发展呢? 马克思怎么回答的我已经忘了,但我也有自己的答案,不过,那就是另外一个故事了。总而言之,“生产力决定生产关系”这样的结论背后,其实可以挖掘的东西很多,如果纯粹把它本身当作一个锤子,看什么都是钉子,就非常有问题了。

最后多说一句,我不是唯心主义者,仅仅是选择了这样描述。

posted @ 2008-06-28 06:49 怪怪 阅读(2526) | 评论 (10)编辑

从DDD说开去,流行方法论和我们的未来

     摘要: 也许这就是人类做事的解决之道: 既然我们的社会还不具有一大堆能够将现实世界的问题和真正艰深的科学理论联系起来的顶尖工程师,也没有出现一群真正的大师拿出对大多数问题解决方案的总结,而事情总是要做的, 那么不如一步一步的来, 让菜菜鸟们跟随菜鸟的优雅,采取次一等的做法总是要比什么都不做来的好得多。所谓山中无老虎, 猴子称大王, 就说明大王存在的必要性了。  阅读全文

posted @ 2008-06-27 05:17 怪怪 阅读(3794) | 评论 (53)编辑

路过的说说, 我那篇文章, 应该发么?

说实话我有点疑惑, 不知道这样做对不对, 虽然那是我的真实想法。

这东西有趣。 设计产品的都去看看。

http://blog.seattlepi.nwsource.com/microsoft/archives/141821.asp

是一封披露的电子邮件, Gates讲述了在Microsoft.com下载Movie Maker的可怕经历, 以至于写了这个邮件敦促改进。 如果Gates都是这个感受, 那么我们设计产品时应该什么样呢?

posted @ 2008-06-26 23:57 怪怪 阅读(1077) | 评论 (0)编辑

也谈优秀: 我们真的必须知道什么吗?

     摘要: 工程人员绝对不要期望自己像研究人员一样生活和工作, 一旦达不到就抱怨。 要知道我们的工程时间, 和我们的生命都是有限的, 而一个工程人员有做不完的事情。如果不停的学习, 大多数时候不过是从一个表面到另一个表面的浪费时间, 所谓的“深入”,不过是个自我欺骗的屁话。   阅读全文

posted @ 2008-06-24 18:24 怪怪 阅读(3941) | 评论 (51)编辑

临时笔记, 有意思的东西

一些编译器理论的简单介绍,和现代Parser研究的新进展。

http://www.antlr.org/article/needlook.html

http://citeseer.comp.nus.edu.sg/440034.html

Tomita(GLR) Parser

Packrat parser (use TDPL)

http://java.sun.com/docs/books/jls/first_edition/html/19.doc.html

http://www.cs.berkeley.edu/~smcpeak/elkhound/

http://www.mollypages.org/page/grammar/index.mp

http://lambda.uta.edu/cse5317/notes/node20.html

http://pages.cpsc.ucalgary.ca/~robin/class/411/LR.1.html

http://en.wikipedia.org/wiki/Memoization

http://en.wikipedia.org/wiki/Comparison_of_parser_generators

http://en.wikipedia.org/wiki/Parsing_expression_grammar



> The author states that he wrote the GLR parser generator solely to
> handle C++ language spec [and someone lapped it up to handle Java].
>
> What exactly is it about OO languages that an LALR(1) parser cannot
> handle?

As the moderator noted, there is nothing about "OO" languages that
LALR(1) parsers cannot handle, but C++ itself is problematic. There
are LALR(1) and LL grammars for Java.

One of the problems with C++, is that expressions and declarations can
look exactly the same (technically, any language containing those the
or of the two productions is ambiguous) and C++ gets around that by
saying, if it looks like a declaration, it is a declaration (forcing
the "or" to be resolved in a particular declaration (and resolving the
ambiguity). However, that resolution is not expressed gramatically,
and one can not take two random context free rules and difference them
and expect the result to be a context free language, which is what the
C++ ambiguity resolution requires one to do.

In contrast, GLR grammars are not required to be unambiguous. Any
ambiguity is resolved by producing a resulting parse-forest that
represents all the potential mabiguous choices and requiring a later
"semantic" pass to choose which parse tree in the forst is the desired
one. Thus, with a GLR parser, one can disambiguate the C++ problem by
selecting the parse tree that treats all the ambiguous expression/
declaration sub-trees as declarations.

The only problem with GLR as a technology is that are no "warnings"
from the grammar processing tool that the language is ambiguous.
Well, there are warnings that the language is not LR (or LALR) or
whatever technology the GLR parser uses as a base. However, some of
those grammars will actually not be ambiguous and some of the will be
ambiguous. However, in any case, once your GLR generator has given a
warning, one either must prove that the language actually isn't
ambiguous or write your semantic phase assuming that the language is
ambiguous and disambiguate the resulting forest.

It is worth mentioning that there are other ways of handling ambiguous
grammars. In particular, one can use predicates to resolve
ambiguities. Predicates allow one to take the difference of two
productions in a controlled manner. In particular, it is possible to
write a syntactic rules that says, try to parse this as a declaration
and if it isn't parse it as an expression. The difference between the
predicated and the GLR solution is that predicated grammars are still
deterministic. There are no hidden ambiguities in a predicated
grammar. If your predicated parser generator gives you an error, you
still have an unresolved ambiguity and if it doesn't the resulting
parser will always construct a parse tree (and not a forest).

I would be remiss if I also did not point out backtracking parsers,
which are another solution to the problem. In fact, all the
implementations of predicated parsers that I know of, use some form of
backtracking in their implementation. General backtrakcing parsers
share the characteristic with GLR parsers that they can parse
ambiguous grammars. Backtracking parsers generally also produce a
parse tree (although in theory they could also produce a forest).
Backtracking parsers have their own deficits though. Many
backtracking parsers will loop forever on some ambiguous grammars.
(Predicated backtraking parsers do not generally have this problem,
although they do not make the same linear time guarantees that pure LL
and LR parsers do(see note)--of course, any parser generator that can
handle a significant class of ambiguous must be inherently non-linear
for some grammars, and GLR parsers have a cubic worst case, same as
Earley parsers.) In addition, most backtracking parsers resolve
ambiguities by selecting one parse tree out of the forest to return.
This is generally done by the order of the rules in the grammar (which
determines the order the rules are tried in in ambiguous cases). If
one looks closely, this is very similar to using predicates
"implicitly" in the grammar. The key difference being that the tool
inserts the predicates rather than the user and does so without
warning and usually without the run-time termination guarantees.

I would like to mention that it is possible to build a predicated
parser using GLR technology, although I don't know of anyone
attempting to do so right now. From thought-experiments I have done
considering whether to implement such a tool, it seems like there
would be some advantages to building such a tool.

Again, I do not want to imply that these are the only techniques for
dealing with ambiguity. For example, Ralph Boland is pursing some
generalization of LR technology that I gather will handle a wider
class of languages and I don't think his technique is any of the
above.

Note: Bryan Ford recently published a paper on a "predicated" parsing
technique that made extensive use of memoization and lazy evaluation
to achieve (if I recall correctly) a linear time guarantee. His
technique shares a characterisitic with general backtracking parsers
in that the order of rules determines what is matched and the the
entire tree is disambiguated that way. He uses an "ordered" or clause
to implement this.

Hope this helps,
-Chris


Chris Clark said (in part):

> It is worth mentioning that there are other ways of handling ambiguous
> grammars. In particular, one can use predicates to resolve
> ambiguities. Predicates allow one to take the difference of two
> productions in a controlled manner. In particular, it is possible to
> write a syntactic rules that says, try to parse this as a declaration
> and if it isn't parse it as an expression. The difference between the
> predicated and the GLR solution is that predicated grammars are still
> deterministic. There are no hidden ambiguities in a predicated
> grammar. If your predicated parser generator gives you an error, you
> still have an unresolved ambiguity and if it doesn't the resulting
> parser will always construct a parse tree (and not a forest)

I agree with Chris about the use of predicates.

Interestingly, the use of predicates alone can some Type 1 power to a
grammar.

For instance:

L1 = {a^n b^n c+} // clearly a type 2 language
L2 = {a+ b^n c^n} // clearly a type 2 language

L1 intersect L2 = {a^n b^n c^n} // a type 1 language

Current research in the area of this class of grammars can be found here:

http://www.cs.queensu.ca/home/okhotin/

See the section on "Boolean grammars." Intersection can get quite a bit of
power out of a formalism.

My most recent paper deals with several difficult to parse languages of the
classical sort, including the particularly nasty to parse:

L = {a^m b^n c^mn}

The only grammar I've seen expressed for that one in classical form is in
Type 0 due to a length increasing production:

  (1) <S> ::= <H><S> | <H><B>
  (2) <B> ::= <B><B> | <C>
  (3) <H><B> ::= <A><X><N><B>
  (4) <N><B> ::= <B><N>
  (5) <B><M> ::= <M><B>
  (6) <N><C> ::= <M>c
  (7) <N>c ::= <M>cc
  (8) <X><M><B><B> ::= <B><X><N><B>
  (9) <X><B><M>c ::= <B>c
(10) <H><A> ::= <A><H>
(11) <A> ::= a
(12) <B> ::= b

Because production (9) is length increasing, the grammar is in Type 0 form,
even though the language itself is Type 1. I'd like to see that grammar
normalized to a Type 1 -- but haven't been able to find one.

The longest derivation I've been able to do with that by hand is aabcc,
which is:

(11) aabcc --> <A>abcc
(11) <A>abcc --> <A><A>bcc
(12) <A><A>bcc --> <A><A><B>cc
  (9) <A><A><B>cc --> <A><A><X><B><M>cc
  (7) <A><A><X><B><M>cc --> <A><A><X><B><N>c
  (4) <A><A><X><B><N>c --> <A><A><X><N><B>c
  (3) <A><A><X><N><B>c --> <A><H><B>c
  (9) <A><H><B>c --> <A><H><X><B><M>c
  (6) <A><H><X><B><M>c --> <A><H><X><B><N><C>
  (4) <A><H><X><B><N><C> --> <A><H><X><N><B><B>
  (2) <A><H><X><N><B><B> --> <A><H><X><N><B>
(10) <A><H><X><N><B> --> <H><A><X><N><B>
  (3) <H><A><X><N><B> --> <H><H><B>
  (1) <H><H><B> --> <H><S>
  (1) <H><S> --> <S>

I started on aaabbcccccc -- but got lost in the shuffle. :-(

If anyone wants to try a purely "predicate" approach to the above
language -- I'd love to see it. (Or if anyone would care to post the
derivation of aaabbcccccc, I'd really love to see that, too.)

The $-grammar I wrote for that one accepts strings in O(n^2.3), and has 6
productions and 2 of those are predicates, but also makes use of 2
phi-expressions, which implies a total of 4 predicates (since there is an
implied predicate with every phi-expression) and at least 2 name-indexed
tries.

Also of note is that I allow for a-expressions in predicates, which allows
for substrings that have been parsed to be concatenated to form entirely new
input that is then passed to the predicates. (The $-grammar for a^m b^n c^mn
uses this.) This is similar to what is known as "length-increasing".

Anyway, a few nights ago, I was asking myself about this formation in C++:

class Foo
{
int inline_function(int x)
{
return __y * x; // __y is used before being seen
}

int __y;
}; // this class is legal

class Bar
{
int inline_function(int x)
{
return __y * x; // __y is an undeclared variable
}
}; // this class is not legal because __y never gets declared

$-calculus was able to handle this ... without any code, accepting Foo and
rejecting Bar -- using all of the above mentioned techniques.

Although the resulting $-grammar uses more than 1 explicit predicate, it
does make use of phi-expressions, and these have implied predicates -- so I
was not able to do it without extensive overall use of predication.

Anyway -- I wrote it up and am looking for somewhere that is looking for a
3.5 page paper on such things. Any thoughts?

[BTW -- Chris -- direct email to you bounces from my account. Is that a spam
guard?]

posted @ 2008-06-20 20:30 怪怪 阅读(1775) | 评论 (0)编辑

方法级AOP: 又一个补丁

     摘要: 方法级的AOP的一种办法, 利用了新的Expression, 比起生成动态代理类那是清凉多了, 使用起来也灵活, 就是表达方式有点丑 :P

这是跟老赵还有脑袋讨论的成果, 感兴趣的可以进来讨论一下。 感谢老赵和他的文章的帮助, 同时也更深刻的感到如果语言的表达方式能提供足够的支撑多好, 大家一起催脑袋干活 :P  阅读全文

posted @ 2008-06-12 23:54 怪怪 阅读(4491) | 评论 (19)编辑

     摘要: 绝对有另你不适的内容, 不想反胃勿进; 基本上是一篇可以定性为“反人类罪”的发泄。  阅读全文

posted @ 2008-06-02 04:11 怪怪 阅读(4950) | 评论 (10)编辑

系列讨论初步考虑的备忘

     摘要: 先把一些相关的内容, 想到的目录记录一下。 这些标题是散乱的, 甚至不是一个层次的, 仅仅做一个备忘的笔记。

顺便说一句, 这个系列不是忽悠大家去用某一门“表达方式更丰富”的语言, 或者给出什么解决方案。 对于大多数程序员, 身处环境和项目当中, 更换语言是不现实的。 更何况说实在的, 现在还没有一门语言能够完美的达到我想要的效果或标准; 即使那些能够做到的语言, 我们可以采取的表达方式也是极其丑陋的。 并且, 在这系列文章的讨论所涉及的一些工作,如对语言本身的改进, 也不是大多数程序员任务。

但是我们仍然可以因为一些深入讨论, 知道问题的症结所在; 从而在能避开的时候避开, 在不能避开的时候, 不会殚精竭虑的去寻求不切实际的解决办法。 同时, 在这个系列中, 我们也可以找出一些外围辅助的方式处理好其中一些问题, 暂时不能治本, 指标也好。 更多的, 我们可以通过讨论,把现今那些浮躁的解决方案先放到一边,努力的去试着看清未来10年一些可能发展的方向。如果10年之后, 你我还在做技术, 即使没有预测准, 这样的尝试也不能说是无意义的。
  阅读全文

posted @ 2008-05-24 09:14 怪怪 阅读(5611) | 评论 (16)编辑

保存个地址, 顺便问个问题~

再更新两个地址:
http://programmersatwork.wordpress.com/john-warnock/
http://programmersatwork.wordpress.com/bill-gates-1986/

更新一个地址: http://www.infoq.com/articles/dsl-on-the-clr

地址: http://www.codersatwork.com/names.html?order=popularity

最后这个是个大牛列表 :)

问题:

具体点拿一堆图片的管理来说, 大多数系统, 都是有一个Picture表, 一个Category表, 一个链接表, 链接表就这两个字段: PictureID, CategoryID。

比如任何一个相册, 用户可能给一张图片一个分类, 但是也可能没给这张图片分类,这些没有分类的图片, 在咱们实现的时候, 是让他们属于“没有分类的图片(或默认分类)”这样一个分类呢?还是就让他们什么也不属于: 凡是用户没有指定分类的, 根本不在链接表内出现。

对应于数据库, 对于用户没有选择分类的情况,这两种做法区别在于在链接表内, 会不会有 {PictureID = 1 CategoryID = 默认分类ID值} 这样一行。

有默认分类的优势在于当用户查询“所有没有分类的图片(或默认分类的图片)”的时候,一句"Where CategoryID=默认分类ID"搞定了, 而且可以统一处理“没有分类,分类1, 分类2....”之间的区别。 劣势却仅仅是我的链接表里比不设立默认分类, 多出很多行。

我的想法是, 是否可以把设立默认分类当成一个最佳实践,无论建立什么系统时, 只要在实质上是一个分类的问题, 都可以采取这种实现; 因为这个问题普通到不再受其他条件的影响。 问题在于有没有不适合的反例,比如有默认分类在某种情况下更糟糕, 我想问的就是这个。

这个问题虽然简单, 不过从我第一次接触到现在7、8年来, 一直没有着急做出判断, 也是不敢轻易判断。 因为我无法判断从事情的本质来讲, 没有分类是不是就是一种分类; 这个问题和0到底是不是规划到自然数有点像; 所以对于我来说,这个问题的答案, 对我认识事物也许会造成连带的影响。

那么如果不说这些虚的, 光从实际出发, 设定一个叫做“没有分类”的分类来简化问题, 是否有存在着不适用的反例呢?

posted @ 2008-05-23 12:31 怪怪 阅读(5037) | 评论 (7)编辑

嗯嗯, 今天很高兴

今天(或者说昨天),见到了AnyTao、周银灰、丁学、 金色海洋、 jilzhang几个兄弟, 不过有一点不爽, 因为昨天休息不好, 老毛病又犯了, 一困就要滔滔不绝的说话,这个可能妨碍了大家更好的交流。 最后都到了我和丁学的大本营, 我还抑制不住兴奋, 拉住他又说了一根烟的废话, 完全没考虑到明天人家还要上班。 在这里向大家致歉。

jilzhang说的不错, 我写文章没有重点, 乱七八糟的东一句西一句, 我考虑是不是以连载或者书(不是出版的书)的形式, 把篇幅拉长, 并且根据我所表达的食物的前后依赖关系进行规划, 然后按部分阐述, 这样是不是能清楚一点。 还是怎么样, 希望大家多给我提提意见。 说实话, 就像大家说的, 每个人发文的积极性也有限, 如果我始终不能提高自己的表达水平, 可能也不会一直这样一团乱麻的继续下去。

还有, jilzhang对持续集成的实践的介绍, 破除了我因为不喜欢Fowler而对CC的反感, 这是一个收获; 我会找机会试试这个东西, 幸亏一直以来我对不熟悉的东西不会评论, 不然如此情绪化会影响正确的判断力。 大家也打破了我想办法混个更高的学历从而当个老师, 以赢得研究时间的不切实际的想法。 这几天我会思考一下, 是不是还是以应用出发, 带动研究。

说实话感觉在程序设计的哲学与表达上, 我应该有一定积淀去支撑我所中意的几个应用了; 反过来讲, 语言设计和编译器技术倒不是很着急的事情, 因为和那些语言作者相比, 我似乎还缺乏很多的体会, 包括制造一个语言的需求。 本来这些应用就是肯定要做的,也许我应该切掉好高骛远的期望, 针对目前可行的应用,全力以赴。 也希望能以这些实践为依据, 更清楚的表达我的理念和具体实践方法。

从AnyTao和丁学那里, 初步了解了某一个敏捷形式过程中的一些重点, 包括如何和客户打交道的经验等, 受到了不小的启发; 这些东西都是我目前的工作生活状况很难接触到的。可惜周银灰和海洋没我这么爱说话, 不过还是从海洋那里初步了解了他的思路。 并且, 一些海洋式的反问, 对我的牛皮也是很好的质疑, 让我注意到我对我的理论的实践和思考, 还存在着不少模糊的点。

总而言之, 今天是不错的一天。

posted @ 2008-05-19 01:51 怪怪 阅读(4749) | 评论 (10)编辑

为什么OO是有本质缺陷的?

今天我在这里说OO表达能力不足, 估计没人会信, 但是这真有可能是问题的核心所在, 如果是这样, 那么用歪了也罢学习困难也罢, 错不在使用者和学习者, 而在于OO自身(这种质疑也不是一天两天了,不过大多数言论都是外延法,强调主观因素, 所以不具说服力)。

这篇文章中的思路首先要归功于songcan兄弟刨根问底的精神和脑袋兄与我的讨论和对我的帮助。

废话少说, 说个关键问题吧。 OO最常见的就是 Teacher.Students, Teacher.Speak(), 也就是说Students和动作Speak作为Teacher的组成部分, 是我们关注的切实存在的概念, 但传统的OO居然没有给出向*系统*描述这个概念的表达方式。 是的, 你我都理解字面意思Speak, 可问题是这个概念在系统内不能表达, 我们就无法用其它机构来处理这些概念。

为什么C#加入delegate以后, 方便了许多? 因为Speak从某种意义上, 可以单独提出来, 作为一个在系统中的实际存在, 并且开始可以对它进行有限的操作了。但这还远远不够, 因为Speak是作为Action()存在, 它自身在业务中的独特性没有特别好的方式去表达。

另外一点就是动静间的鸿沟。 C#在Strustroup这些人的看法里, 并不属于真正的静态语言, 但是它给出了一个静态的外表。当我们进行描述时使用的是静态的方式, 我们就必须有静态的方式处理它们, 否则这里面就存在裂缝。 如果大量的反射, 那么我们何必不直接使用动态语言呢?

JS大家都接触过, 比如

obj["someAction"] = function() {}
obj.someAction()

那么C#拿着反射出来的MethodInfo搞来稿去,和JS的方式比丑陋的多, 这样的方式有必要去学吗? 如果一门静态语言, 大家越来越多的是在使用这些, 或者通过那些框架、工具间接的使用这些, 这难道说明这门静态语言, 或者基于这门语言的OO方法, 越来越强大不成? 只能说这种方法因为自身的问题, 无法继续提供足够的支撑了, 不得不求助于外部设施。

说实话, 如果一个语言, 表达重要的概念用到的那种表达方式, 比如类型, 它本身不能被操作的话, 那么它存在问题是必然的。 C#可以操作, 但提供的主要操作方式, 都在运行时, 通过反射。 可我们表达概念时, 却在编译前, 也就是说我们的表达注定是不完整的(或不直接的)。 反观动态语言, 为什么越搞越火, 还不是因为人家干脆都放在运行时了, 完整了; 而且在表达方式上优化过, 直接在语言层面支持, 这不是反射所能比的。

如果我每句话缺几个字, 大家感觉如何? 一个不完整的表达, 你觉得什么样的工具或者方法论, 让你能够毫无障碍的完成模型的建立呢?

P.S. 再次感谢以上二位和与我讨论过的各位。

另外, F#我也试过了, 这些问题全部存在(妈的,终于理解SICP某一页的小注释中质疑流行语言的类型系统的原因了), 根本是白搭: 实际上这本来与是否FP也没啥联系, 只是我希望作者按照脑袋兄跟我提出的那种意图和方式, 在编译器的层面做了一些改良。我的最后一线希望成了梦幻泡影。

我现在的建议是,要么选择一门动态语言, 要么选择C++和D(其实C++是个很差的选择); 如果暂时不能更换, 那就不要考虑太多了, 承认问题的存在, 并且尽量弥补就是(似乎.NET平台上的语言目前就是这种状况, 我自己也是在鉴于现实原因没法换的境地)。

最后重申一遍: 不要因为OO存在这样那样的问题, 就放弃OO的尝试。 我的想法是, 作为一种当代最流行的方法, 没有一定程度的了解是不行的, 就像牛顿定律一样。 所以我倒是认为, 对OO的深入思考和练习, 虽然一时疑惑, 也绝非没有好处的; 尤其是当我们知道它可能存在问题这一点, 就更可以放开心态了。

过去一个高人对我说, 想学好数学先学好数学史; 我数学史不咋地。 今天我要说我们有一个大好机会, 因为我们就在历史里(这个历史看来还要持续几年); 如果我们认为OO不过是个大忽悠,不屑于学习OO体现了自我相对于云云大众的明智, 那么明天会如何, 就不好说了。

剩下的, 就是等脑袋兄的编译器小改款出炉了, 大家一起拿鞭子抽他干活...

posted @ 2008-05-17 07:31 怪怪 阅读(3670) | 评论 (9)编辑

漫谈数据存取与对象设计

     摘要: 本文介绍了几个问题的某些特定的解决方法, 除了这些方法, 还有很多其它的方法。 要不要使用它们,关键在于我们对碰见的情况是如何判断的。 只是一概而论却忽视了衡量必要性、 适用性的工作是不行的; 进行判断的时候, 忘掉所有的面向对象原则和建模指南吧。 另外一个情况就是, 也许“程序本身需要组织和管理”的需求是突然发现的, 重构这一话题的流行,也足以证明一开始就固定一个漂亮设计的风险。

这也是一般程序员的饭碗所在, 如果有一个一劳永逸的方式, 那么它很容易被固定下来, 减轻工作量,可也意味着这些地方不再需要程序员了。  阅读全文

posted @ 2008-05-13 20:05 怪怪 阅读(3149) | 评论 (27)编辑

晕了

没事又琢磨下DLinq, 顺便关注了下Entity Framework, 总感觉是走在了错误的道路上。

整体工作量并没有下降多少, 而复杂度却在上升; 效率没有上升多少, 而灵活性却在下降。

如果说大公司是吃屎的, 跟随的都是挨忽悠的,这不是我的作风。 不是怕得罪人, 而是不客观。

我像是裸泳的吗? 糊涂中。

Update:
说点题外的, 很可能大多数时候我们对一件事物的执着来自于自我价值肯定的心理需求。 这种心理需求用好了,是成就自己的动力; 用坏了,就容易产生误导自己的错觉。

所以要谨慎、 谨慎、 再谨慎。看似针对外部问题的判断, 有时候恰恰需要仔细衡量的是我们的内心。

Update:
有个可以类比的思考: 我们刚接触ASP.NET的时候, 甚至DreamWeaver的时候, 感觉一切托托拽拽多么简单; 最后呢?

隐藏复杂度不等于更好的掌控了复杂度, 转移或转化问题不等于真正的减少了问题。

剩下的就在于如何分辨两者了。

posted @ 2008-05-12 11:41 怪怪 阅读(1075) | 评论 (8)编辑

我们应该讨论什么? 就面向对象的讨论所引发的一些思考

     摘要: 面向对象不是唯一的方法论, 也不太可能是最完善的一种方法论, 之所以流行, 其深刻原因也不是我们能回答的。 只是提醒大家, 有一种现象, 叫做劣币驱逐良币(我并没有说它一定是)。 但是无论好坏,现在面向对象的周边配套设施却是最齐全的, 考虑到这一点, 不逐渐深入掌握面向对象的各方面常识, 对于我们平时的顺利工作来说又是不行的。  阅读全文

posted @ 2008-05-11 16:51 怪怪 阅读(3223) | 评论 (29)编辑

对Singleton的实现方法做一个总结

     摘要: 说说Singleton的三种实现外加一个变种和一些细节。 还有什么没提到的, 大家也来讨论下~  阅读全文

posted @ 2008-05-10 02:02 怪怪 阅读(4416) | 评论 (29)编辑

不错不错

刚才上了好久不看的某站上瞅了两眼, 居然不少人开始认为这么多年来折腾这么多“大词”是缘木求鱼了。 也有人有胆量说最理想的编程方式就是在“php里一顿乱写”了, 更有人说绕着几道弯弄来弄去, 不过是“在数据库里读读写写”。

有救了。

Update:
顺便记录俩链接, 更准确的说是记录俩词, wiki上的文章不会学到什么, 不过相关词汇就全在哪里了, 未来找真正有用的东西的时候, 记不住的英文单词可以先到这些文章里找。

“突现论”在Wiki上的说明, 个人认为这门学说在很多问题上有点胡扯, 至少国内这方面某学者的著作有点胡扯。 不过具体到某一个特别现象,可能它倒是一个不错的解释工具。 比如自组织的一个实例, WWW, 也许可以用这方面的理论来思考一下。 问题是, 如何得到那个什么边界呢?
http://en.wikipedia.org/wiki/Emergence

这个, 和我最近的一些思路有关, 不知道怎么翻译? 嗯上面提到的某站,在这些方面倒能起到一个不错的提醒作用,毕竟国内也没几个集中讨论FP的地方了,虽然我的思路和FP没那么紧密的关系, 但是却可以受到FP的启发。
http://en.wikipedia.org/wiki/Continuation
http://en.wikipedia.org/wiki/Monads_in_functional_programming
http://en.wikipedia.org/wiki/Category_theory

posted @ 2008-05-08 07:23 怪怪 阅读(1004) | 评论 (3)编辑

Knuth访谈: 老将出马, 一个顶俩

     摘要: 大家追潮流追的也不少了, 也看看比大牛还大牛好几倍的家伙怎么说; 听见些不同的声音, 总比铺天盖地全是流行歌曲, 要强一些; 别搞得好像一些明星加商业宣传, 就代表了真正的计算机科学家的看法和发展趋势似的。 其实很多时候, 我们认为的大势, 总是那几个人或几个团体再表演罢了; 我真正担心的, 是在那些似是而非的学问上花费过多的精力, 最后才发现都是一场空。


如果不知道D.E.Knuth是谁, 可以自己Baidu/Google/Yahoo/Live(排名不分先后)一下。 原文很长, 截取并胡乱翻译了三段, 关于单元测试 、 极限编程两个时髦东西的, 和关于可重用代码这一面向对象一直所关心的主题的。 这老人家也只是发表一下看法, 并没有说为什么, 但是呢, 我觉得可以当一个警钟敲了一下, 有没有道理的, 权当一个提醒, 一个敦促自己思考的契机吧。


另外, 那些对流行不感冒的兄弟, 也不用觉得自己太落后了, 至少肯定比明星梯队权威的人和你一样土; 问题的关键是写出像样的软件, 不是么?  阅读全文

posted @ 2008-04-29 14:37 怪怪 阅读(4390) | 评论 (36)编辑

闲言碎语

     摘要: 底部含有令人不适的内容, 请酌情观看。  阅读全文

posted @ 2008-04-21 16:34 怪怪 阅读(1892) | 评论 (12)编辑

Utility Wish List

最近想写几个小软件, 不过最近估计没啥时间, 在这里记录一下,以后一个一个完成。

谁要是感兴趣也可以共同参与进来, 一般来说除非特别明确的基于.NET平台的任务, 否则只使用C++。

初步定为开源的, 谁要是有在国外卖共享软件的经验, 也可以合作, 但最好可以保留有开源版本的。

1. 一个编辑照片的小软件, 原来给别人开发过一个, 但是有针对性, 而且代码不小心让我全弄丢了。 现在DC这么普及, 这种软件需求量有一些, 看国内一些开发者也在国外卖, 心里有点痒痒呵呵。 说白了, 就是把一些成熟算法打包, 一键式的完成大型软件得好多步骤的特殊目的的应用。 可能描述的有点不详细, 不是那种只有点增量变暗什么的软件, 而是可以变形(拉伸放大局部什么的), 去脏东西(电线杆什么的), 弄完图片一般人看不出来改过那种东西。

2. 一个简单的批量转换编码的软件。 现在用英文系统, 国内很多下载回来的文件都是GB2312的, 搞起来很麻烦。 这个最容易写, 有空顺手就给弄了。 最终就是右键单击, 然后选转换, over。

3. 一个虚拟驱动器和上面文件的小软件, 需求是这样: 比如现在网上下回来的高清TS都是好几个文件, 如果合并成一个, 这个合并过程又慢又需要很大硬盘空间; 不合并播放时切换文件太慢了。 让用户直接选几个文件, 加入虚拟驱动器, 就直接被虚拟成一个文件。 使用这个文件时, 比如播放, 由这个虚拟驱动器处理并转发。 这样对播放器来说,就是平滑的一个文件了。 这个有点难度, 不过我稍微调查了一下,还是有比较清晰的路子的; 最重要的可以熟悉一些平常干高阶编程不会了解的东西。

暂时就是这些吧..

posted @ 2008-04-15 11:16 怪怪 阅读(1668) | 评论 (9)编辑

随便说两句: 表设计兼一些设计分析的讨论

一个兄弟的问题:

1. 比方说有一个学生选课系统,设计老师,学生和课程等实体,是不是为了扩展或者说为了灵活性亦或为了更OO应当在实际的应用中加上person这个基类? 
2.再有比方说老师有教授和讲师,他们有各自不同的属性,如果不考虑数据的持久化,那么这个好像很好设计,但涉及到保存到数据库的时候,好像就很难处理了,在现实中我们应该不会有教授表老师表和讲师表,也许只有一个老师表,而会出现标志位的字段判断是否是讲师,是否是教授,但如果这样一个类对应一个数据库表应该是不错的选择, 这样的话,实体类就应当有一个老师类就可以了,教授类和讲师类就没了存在的必要,那么OO继承的优势何在?对于这样的问题解决方法是什么呢?


关于建表和对象继承:

首先, 我觉得如果你对面向对象设计的信息系统感兴趣, 可以看看Martin Fowler的《企业应用架构模式》。简单的说两句, 对于一个继承体系, 至少有三种建立关系模型的方式:

1. 一个老师表, 但是这个老师表, 同时有字段对应教授和讲师的属性, 一个教授的行, 其讲师的字段是空的, 一个讲师的行, 其教师特有的字段是空的。 对于很多现代数据库来说, 其冗余的Cell是不会占用存储空间的。

2. 假设没有老师这一具体职位(也就是说老师是抽象的基类),一个讲师表, 一个教授表, 这两个表具有一些相同的字段, 既教授和讲师共同具有的属于老师的特性的字段。

3. 有老师表, 讲师表, 和教授表三个表。 讲师表仅存储讲师的特性, 教授表仅存储教授的特性。 继承体系可能是这两种(讲师<- 老师 -> 教授),或(老师->讲师->教授), 但无论是哪种, 子类通过父类的ID, 和父类表向链接。 比如, 无论多了一个教授, 还是一个讲师, 老师表里都会增加一条老师记录, 如果是讲师, 同时在讲师表里插入讲师特有的信息, 如果是教授, 则同时在教授表里插入教授特有的信息。

所以, 对于一个继承体系来讲, 不见得在现实里只有一个表。 另外一点, 我个人认为, 这些不同的表的划分方式, 其实即使没有面向对象设计, 也是合理的, 同时自有其判断依据: 比如方式3, 有些场景, 我们仅仅需要老师的那些特性, 所以仅存取老师表即可; 有时候我们可能仅处理教授的特性, 而那些作为老师的共同特性反而不关心。 一旦我们关心全部特性, 我们可以将表连接起来。

以上三种方式, 都有一个前提, 既讲师和教授, 都有比起其父类, 更多的特性。 如果讲师和教授, 仅仅是身份不同, 像你说的, 最多有一个标志为标识其身份,我们不谈面向对象, 就谈对这件事的认识。

在现实生活中, 讲师和教授也许是有很多不同点, 以至于我们必须明确的分割这两种身份。 但是我们就我们所处理的任务的角度, 他们或许没什么不同: 系统内部只关心他们作为老师的一些特性; 而一些差异, 则仅仅是是一个子特性, 没有必要甚至不能够,上升到让这两种身份在*任务的视角上*产生真正的差异。

比如: 我们给不同身份的人发不同的工资。 这些仅仅是我们根据特性展开的, 其具体内容属于另一范畴的东西, 对于老师这一个概念来说, 身份只是一个很普通的标志, 就好比他是男还是女一样。 因为大多数关心的主要任务和这个属性关系不大, 所以就不会在系统内部设立两个不同的概念。 比如男的上男厕所, 女的上女厕所, 这是一个额外的规矩, 是在与人这个概念关系不大的其它部分进行的; 但是如果我们任务关心的问题, 就是女人和男人的差别, 情况则不同了。 比如女人和男人的体貌、 行为、 性格, 这些特点如果是我们要处理的, 很显然, 我们应该明确划分这两个概念。 从面向对象、特别是继承的观点来看, 我们需要至少两个对象; 当我们有时候同时关心男女共同为人的特点时, 我们还需要一个叫做“人”的基类对象。

在建表时, 也就会产生我上面所说的三种方式的不同差异。 至于三种方式的优劣, 暂时不能逐一展开, 不过Fowler那本书里都有提到; 不过读哪本书时, 可千万别当成什么金科玉律, 肺炎的种类很多, 不是吃茴香都能治的。

闲谈:

不过我们至少可以看出, 我们如何建表, 如何找到合适的模型, 并非是照搬现实生活里存在的概念的; 而是从我们的任务的视角上看过去, 存在哪些概念。 后者的判断, 在于我们关心些什么, 关心的这些内容, 造成了哪些程度上的不同, 有很大不同的时候, 我们需要不同的表达, 没有不同时, 我们就采用统一的表达。 而类设计和表设计, 只是我们表达的体现而已。  那么, 你所面对的问题, 从各方面来看, 需要几种表达方式才能完善呢?

同时, 我们在这时候, 不要过多的去考虑全局到具体, 而是把问题割裂开。 这个事情和谈恋爱正好相反,粘在一起的东西, 扯开比较费劲; 而把东西粘起来, 则相对容易。 这是因为我们人脑同一时间可以理清的东西有限。 所以我们要明确的认识到, 哪些东西可以规划到“男人上男厕所, 女人上女厕所”这样的外部规则, 哪些东西满足“男人和女人不同的特征”。 如果一时不容易分清, 至少我们在信息的量上可以做把握(不过这样把握的方式其实不是实质性的, 随着理解的深入, 就要放弃了), 后者往往涉及到一系列信息, 而前者中“男”“女”仅仅是一个用于填入规则的标志。

当然, 我们设计了一个表, 其中有一个字段存储“男”、“女”, 进行面向对象的设计的时候, 我们照样可以弄出一大堆类, 继承人这个类。 当我们调用, 人.上厕所()时, 就各去各的厕所了。 面向对象一般鼓励以这样的方式, 去给出统一的接口(比如这个例子里“人”)。 其优势在于, 当我们多出其它性别时, 比如“半男半女”、“不男不女”, 那些调用“人.上厕所()”的代码, 全都无需改变。

这里有一个假设, 在于“人”这个接口, 比如具有一些属性, 具有一个“上厕所”的方法, 这个接口是稳定的, 不会改变的。 当我们在进行设计时, 要衡量这个假设是不是成立的。 比如上厕所这个行为, 有可能在未来变化为“上厕所(带手纸)”, “上厕所(没带纸)”, 这样一个接口的变动。 很多面向对象设计只所以问题连连, 就在于做出了时效性太强的假设。

为什么这么说呢? 因为接口是有很大概率会变化的, 其区别仅仅是一个月之内就变, 还是这个系统用了3年才变。接口一旦发生变动, 我们往往就要为当初获得的好处埋单了。   所以如何设计, 有时候不是一个绝对化的问题, 而是一个想办法付出最小代价的问题。

对于上厕所, 我们可以统一的把上厕所的具体问题外包出去, 比如针对各种情况可能采取的各种方式, 这样我们就产生一个“上厕所的办法”这样一个外部概念。 我们可以想像, 当一个人脑子里有这个概念的时候(“人”这个类别的对象持有某一“上厕所策略”), 就可以根据判断“我是女的, 我上女厕”、“我没带纸、找张报纸”进行行为, 你可以说这些是这女的想的, 但是你也可以认为这些仅仅是外部规则, 这女的只是按照规则机械的行动而已; 这后一种看法, 实际上使得我们容易在计算机上设计。

这时候, 我们无需使用继承的体系, 而是采用“人.上厕所(策略)”这样的接口, 那么如果我们所关心的“男”、“女”, 和带纸没带纸一样, 仅仅是上厕所策略用以判断的素材而已; 这样, 我们就不需要男人类和女人类了。

从以上例子来看, 类的设计和表的设计, 不是说一定要有必然的联系。 因为既然我们写了非存取的代码, 就说明我们除了可以记录下来的特征, 还关心其它的非可固化性质的行为, 那么我们如何设计类、 对象, 则必须从这些行为以及系统中各个对象交互的视角上出发, 而不是考虑我们的表如何设计的。 注意, 这不是说我赞成以实体类去设计表, 关系模型关心和表现的是事情的另一个侧面, 所以设计表恰恰不能从对象设计倒回去。 它们之间应该是正交的, 不要存在一个依赖另外一个这样的耦合。 如何让他们兼容, 需要且应该做额外的工作。

当上面的例子简化到一定地步, 比如 if(男) ... else ...时, 我们也不需要什么策略的对象或者类, 有一些用于体现策略脚本处理即可。 到了这个地步, 我们也许一个实体类都不需要有。 我们就简单的把系统看作根据具体情况作出判断和处理的策略系统就可以了, 这时候我们需要的仅仅是信息的载体, 这就是为什么我经常会说, 当产生了贫血对象后, 我们要考虑的不是把它变复杂, 而是看看能不能把它从系统中抹去的原因。 很多时候, 贫血类比起一个通用的信息载体, 除了字段和属性强类型的好处, 仅仅发挥一个自身标识的作用; 但是当我们调用“人能做的事情静态帮助类.上厕所(信息载体)”的时候, 实际上我们已经隐式的传递了这个标识; 我们也可以设置一些具体的手法, 保证安全。

总结:

最后, 我们再来看看这些区别, 强化一下印象:

1. “人能做的事情.上厕所(信息载体)”、“人.上厕所()”和“人.上厕所(策略)”之间如何取舍, 在于复杂度, 复杂度上升到一定程度, 我们要采取后者; 这是为了避免前者“上厕所”这一Rotine其内部复杂度上升的太高, 或者被频繁修改。 另外一个更明确的判断点在于, 人是否带有可变化的状态; 上厕所这件事是否有很多的方式。

2. 假设我们采取了含有“人”这一样一个概念的具体表达的设计, 人这个接口如何保持稳定是我们要注意的。 比如“上厕所”这一行为隐含的变化, 或者又增加“吃饭”等行为, 都属于接口的不稳定, 如果这种不稳定在短期内就会出现, 我们应该把行为和规则外包给其它概念, 而不是让它们依附在人之上。 如果我们一出生就是狼孩, 本来我们也不会具有这些概念所指的行为; 并不是说“主语.谓语”, 这样的设计方式就是合理的。

3. 我们是否需要“男人”、“女人” 或者 “讲师”、 “教授” 这样的继承体系, 可以这样判断: 必须共性大、同时差异也大。 组合比继承好, 这是从95年《设计模式》以后被大家广泛接受的原则。 很显然, 共性和差异同时非常大的情况不是特别多见。 也许我们平时见惯了我们的aspx页面继承于Page, Page又继承于TemplateControl和Control。 且不说合理与否, 这并不能说明需要继承的情况很多。 因为这样一个继承, 使用了10000遍, 它其实还是一个继承。

4. 表设计和对象设计是两码事, 要按照各自的特点来做; 同时追求两边的合理性, 要付出的代价就是多做中间工作, 这些上面说的比较详细, 就不多说了。唯一可以说的是, 在成本上考虑, 我们要做好折中的选择。 更多的则是, 无论哪个设计, 无论什么设计方法, 我们别想太多, 更多的要找出我们关心的全部内容, 而不要把在现实生活中的知识带入过多; 因为对我们要解决的问题所在视角, 这些知识可能就成了不必要的偏见, 或者至少像用大学物理解释初中物理题。

这些问题其实在学习面向对象以后, 做类似的信息管理时, 非常普遍。 我想你先问问自己, 你自己想采用什么样的设计呢? 其次, 看看自己能不能找到这种设计的扩展或灵活性的好处。很多时候, 我感觉咱们想面向对象的冲动, 是因为不面向对象, 好像就不是一个设计, 简陋了些。 首先要克服这个心理。 如果找不到一个设计的好处, 而非要面向对象的话,即使存在一些好处, 也不是我们可以掌握的; 如果反而添了不少麻烦, 这些麻烦也不容易被找到。

总而言之, 我觉得, 不求巧, 但求拙, 不给自己的思路下套子, 不引入过多的杂念, 是设计的一些好的准则。

posted @ 2008-04-13 22:33 怪怪 阅读(3950) | 评论 (34)编辑

也论标准: 统一是啥好事情?

要说标准, 尤其最近的讨论都说到9X年了, 当年最不标准的似乎是Netscape, IE才是标准的先行者。那会儿这组织那机构的都干嘛去了?其实真正不作为的恰恰是其他人, 让Microsoft一统江湖了, 却又穷则生变, 开始知道应该发挥作用了。

另外如果世界上只有一种标准,而这种标准就是微软的,难道微软就真不会进步了吗? 不出新产品, 怎么挣钱? 不过是因为重心的转移制造了一个机会, 让一些“正义者”又回到了舞台上罢了。

要说Microsoft没错, 一个产品熬6年也确实真够可以的....,不过这种错, 充其量只是公司策略上的失误; 如果Netscape还在, 大家就更要骂娘了。 何况IE6的统治期虽然有种种不如意, 但是很多Web开发人员得到了一个相对平静的环境得以成长。

这就好比Windows 3.1 - Windows 9X再烂, 还是在90年代提供了一个相对稳定的环境, 培养了大批程序员。 如果Linux、UNIX、MacOS、OS/2那会儿全都活得生龙活虎, IT业进步是更快还是更慢可真不一定。 这叫什么来着? 原始积累的过程, 不过积累的是从业人员罢了。

现在Microsoft开始出让市场了(当然不是他大公无私),如果一个公司自己的错误, 要为全世界Web开发者的苦附上责任,那么考虑到如上这些,我们是不是应该反过来感谢微软呢?

我自己不太喜欢考虑这种问题, 而且说实话, 我不是一个纯粹的Web Developer, 但是我认为这对Web Developer也不是啥坏事。

你们想, 如果IE 6/IE 7/IE 8/FF/Safari/Opera/KHTML(靠好长的列表)平均分配名额, 就需要更多的技巧, 也就是说, 多了一种工作或工作量变大了, 相对掌握这些技巧的人,工资或者工作机会也更多了。

最好将来SilverLight/Flash/增强版SVG+JS也三分天下,接着微软原来的VML小组也复出, 干脆PNG文件也变成可编程的。 然后Google也出自己的东西, Sun的Applet东山再起。 一定要保证用户的机器有这个就没那个, 有那个没这个,最好和3721他们一样,互相卸载着玩。

嗯不错, 大把的银子啊, 向开发者们砸过来吧~

我这是真心的说, 一点反讽的意思都没有。 毕竟大多数人都在做基于这样那样产品(不仅仅是Web领域)的技巧性的工作, 并靠这些东西活命呢。

统一呢? 最终节约的是商业组织的成本而已,真的就让Web Developer少受痛苦吗? 不知道肚子饿苦不苦呢。 无论什么技术,发展的越慢,对我们这代开发者中的绝大多数来说, 技术生命就更长。

让百家争鸣, 各有个的标准来的猛烈些吧~~。

posted @ 2008-04-09 18:47 怪怪 阅读(3280) | 评论 (45)编辑

我终于有个偶像了

说实话, 我不关心, 也不喜欢政治, 对体育也没啥兴趣。 虽然我佩服Carmack, 佩服Gates, 佩服老毛, 佩服爱因斯坦, 但我没有偶像。就像大家看到的一样, 在我这里只有质疑。

 不过今天不同了,我终于有个偶像了。其实这样的偶像, 应该还有很多; 只是只有他/她们出现在公众视野, 才能被大家所知。 不是因为她为谁做了什么, 只为一个人忠于自己的梦想, 忠于自己的职责,敢于笑对任何困难的精神。









=======================================================

(转)央视境外传递火炬手接近尾声 轮椅剑客金晶脱颖而出
http://sports.sina.com.cn 2007年11月26日04:30 新闻晨报    □晨报记者王治明
  
经过四个多月的选拔,先后有6位出众的市民,在联想和《新闻晨报》共同搭建的选拔平台上脱颖而出,并在央视“你就是火炬手”的节目中表现优异,从而 成为联想奥运提名火炬手。他们是在成千上万报名参加火炬手选拔的普通人中的佼佼者,他们身上所折射出的“具有不断探索、超越的奥林匹克精神”,让他们成为 了平民“明星”。而金晶,则是提名火炬手中的幸运儿,她获得了即将远赴巴黎传递圣火的机会。对能去法国传递圣火,金晶非常高兴:“目前我还是队友的陪练, 如果能到巴黎传递圣火,想联系我们法国轮椅击剑队的队友,和他们碰个面。”
  
获选感言只要心里有阳光,眼睛里就都是温暖
  
真正成为火炬手,要等12月底奥组委正式盖章才能算呢,所以我的心情还没有很激动吧。但是,我被选上了,我真的很开心,真的,让我感到了很久不曾有 的感动,别人对你的认可和关爱,那么多人对你的呵护,让我知道了这么多年的坚持没有错,我也会带着所有人的期望走下去,带着我的勇气、带着我的微笑、带着 我的快乐,让所有的人知道:真诚的微笑可以温暖任何一颗悲伤的心,坚持自己的信念,一定可以感染更多的人。让每一天的阳光都很灿烂,让每一天的生活都过得 快乐,让身边每一个人的心都是温暖的。
  
当我拄着拐杖支撑起一条腿走在路上的时候,曾不只一次碰到过有些家长说自己的孩子和我 一样,但是不肯出门、不肯见人,他们希望我留下联系电话帮着劝导,可惜的是,都没有打过来。我觉得有时候仅仅靠个人的力量是很困难的。的确,走在路上,我 也能感觉到身边的目光,相信大部分人的眼光并不是恶意的,有部分佩服、有部分好奇、有部分怜惜,其实就看你自己是怎么看的。这次在火炬手境外选拔的时候, 说过的话中令我自己印象最深就是:“只要心里有阳光,眼睛里就都是温暖,这就是微笑的力量。”
  
我参加火炬手的选拔,也是希望能给一部分不如意的人一些鼓励,在“我想、我做、我超越”精神的感召下,希望火炬能让我心中奔跑的火种再次熊熊燃烧,希望举着“祥云”,超越我的人生,也鼓舞更多人!
  
参选心情是圆梦也是为了给更多人带去希望
  
又一次北京之行结束了。虽然这次是在提名火炬手中选拔境外火炬手,但是却明显感到了气氛和上次选拔的不同,可能是肩负的责任不同吧。晚上最后一场录 制好之后在聚餐时,几个导演都哭了,从这档节目中收获了感动,可同时也留下了遗憾。有导演说,当她看到那些选手在台上紧张得都说不出话的时候,真的很难 过,不知道自己做的是对还是错。给普通人一个展示自己奥运梦想的舞台,有辉煌也有压力,这个同奥林匹克的竞技场也有雷同之处。
  
许多选手明显没有上次国内竞选时那么自如了,背负着城市和单位甚至是一个群体的期待,每个人都很优秀,都有自己感人的故事和奥运情结,可是这毕竟是选 拔,总有人晋级、有人被淘汰。我们中也有人是带着希望来参选,希望当选火炬手能有更多的机会宣传我国的历史文化、能让更多的人传递爱心、让更多人关心爱护 残疾人和弱势群体等等。这不仅仅是圆一个奥运的梦想,也是给更多人带来鼓励和希望。
  
对轮椅与剑的独白我知道,我并不是一个人在战斗
  
记得2004年奥运会没有能去,除了失望真的还有彻骨的痛,这种痛苦绝对不亚于失恋,当时看着曾经陪我走过两年的剑不禁哭了,觉得自己对不起它们,陪我打了那么多场比赛,因为主人的不争气,却没有能够去奥运赛场一展身手。
  
看着我的比赛轮椅,心里不禁又一痛,7年了,跟了我7年,摔过、撞过,就像自己最亲的战友,默默无闻地支持着我。现在这辆轮椅已经很破旧了,去年国 家队换轮椅的时候,我没有用新发的,还是用我这辆第一次去国际比赛就用的紫色轮椅,因为它是朋友、是兄弟、是战友,虽然我没有出息,从来没有带它登上冠军 的领奖台,也没有和它一起走在奥运赛场的赛道上,但是仍然不离不弃。现在它已经很旧,甚至可以说很破了,但是依然结实,就像我一样,不知道我们还能在一起 奋战多久,但是我知道并不是我一个人在战斗,随着进攻后退的摇动,是我和轮椅一起作战,是我们共同的战役……
  
谢谢你,我的轮椅,只要我还在训练一天就不会抛下你,因为你是我最亲密的伙伴!

========================================================

(转某新闻段落)新华社巴黎4月7日奥运专电(记者张荣锋、马邦杰)

从金京懂事起,奔跑就成为了生命里的旋律,从卧室跑入客厅、从楼上跑向楼下、从教室跑到操场。对金京来说,奔跑就是世界上最幸福的事。可九岁那年,命运和 她开了一个大玩笑。恶性肿瘤——横纹肌肉瘤,判定了这个小女孩的命运,奔跑永远只能是梦想了。为了保住生命,她只能接受截肢手术。
    
失去了一条腿,并没有让金京失去生存的信心。虽然以后陪伴着她的只是轮椅和拐杖,但是对奔跑的渴望始终是她心中燃烧的火种。2001年7月13日,也就是北京申奥成功那天,她加入上海轮椅击剑队,当然还有个原因就是喜欢佐罗。
    
对她来说,参加轮椅击剑遇到了很多常人难以想象得困难——金京的身体有些瘦弱,个子不高,这样一来就意味着她的手臂相对比较短,力量不足,高位截肢 也使她在防守上有着一定的劣势。然而这一切都不能阻挡她,坚强意志和奥运精神支持着她刻苦训练。很快,金京在属于她的赛场上取得了优异成绩,几年内拿到了 多个世界级比赛奖牌。通过刻苦训练,金京不但在击剑赛场上取得了优异的成绩,还在电视节目“舞林大会”上有了几近完美的表现。
    
阴错阳差,金京没能参加雅典残奥会。随着年龄的增长,她也将无缘北京奥运会。正当她为无法参加奥运会感到遗憾的时候,“你就是联想奥运火炬手”的大字印入她的眼帘,她的毅力让她赢得了自己的奥运空间。
    
对于未来,她充满信心。“一路走来,受到了很多人的肯定,我对自己的要求要更高。我能够成为一名奥运火炬手,证明残疾人能做到的事情有很多,”金京满怀期待地憧憬着未来之路。
    
金京最喜欢的一句话是《乱世佳人》的收尾句——“还有明天”

posted @ 2008-04-09 04:36 怪怪 阅读(131) | 评论 (7)编辑

是他妈傻子写的么?

最近帮一个朋友做些Community Server改造的工作, 说实话, 我早就对这玩意深恶痛绝了, 也许是太长时间不干, 恶心劲儿过去了, 也就勉强答应了。

今天看了一段代码,我就他妈那一个操, 这是他妈傻子写的么? 傻子能写出二十来万行代码外加几十万行杂七杂八的aspx以及配置文件, 也真不容易。

想想这玩意儿居然也卖的出去, 卖的还挺贵, 我真得琢磨琢磨了。 说实在的, 虽然Discuz大多数地方和丫估计在一个水平线上, 有些涉及到认识方面的水平还稍低(虽然Community Server就一大杂烩), 不过Discuz绝不会有这么傻的开发人员。

那些Community Server对一些问题的正确认识(其实也就那几点), 也绝非因为他们脑子更好使或者知识更多, 只不过正好处在IT行业的风口浪尖, 受外部环境影响, 不小心就按照正确的方式理解了罢了。问题是理解对不代表用的好,所以CS的维护和二次开发成本居然会那么高。

微软居然也敢用它的产品,这说明什么?美国人的脑子怎么长的真是值得研究一下; 顺便又想起前阵子美国程序员效率是中国程序员10倍的××言论了。严重支持Discuz好好完善, 进军美国。

说实话, 这世界上烂货很多, 水平高的组织很少, 好