2006-05-24

为了安全起见,sourceforge只允许sftp进行访问。有了sftp,我们就可以把所需要的文件上穿到远端服务器。比如页面需要的html和php文件。

访问sourceforge的sftp是非常简单的。
只要使用你sf注册的用户名密码登陆shell.sourceforge.net就可以了。

这里推荐一个好用的sftp客户端winscp,好了现在可以开发你的网页了。

2006-05-21

SourceForge作为开源软件(OpenSource Software)的大本营,一直是开发者最钟爱之一。能够在上面有一个自己的项目是很多程序员的梦想。而SourceForge刚刚又提供了Subversion的支持。那么我们就说一下如何使用Subversion以及提供的homepage的支持。

你要有一个SourceForge的帐号,还有一个你自己申请的项目(例如KuteEdit),假设你的身份是这个项目的管理员。
首先,你要进入这个项目,然后选择管理(admin)。
Admin Link
这个时候,你可以看到有一个Subversion的连接,
Subversion Link
进入这个连接,然后启用你项目的Subversion。
Enable Subversion
接下来,进入人员管理(Members)的页面,
Members Link
编辑自己(还有其他开发者)的权限,给自己Subversion的访问权限(这里的Subversion权限,要么就是都有,要么就是都没有)。
Use Subversion
接下来,你就可以进行Subversion的使用了。

使用https://svn.sourceforge.net/svnroot/project_name,进行访问。例如
svn checkout https://svn.sourceforge.net/svnroot/kuteedit kuteedit
checkout是无需进行身份验证的(至少我得是这样的)。如果你是一个开发者,那么开发完毕之后,你可以使用svn commit进行提交,用户名和密码就是你在SourceForge注册的用户名和密码。

这个时候,你就可以使用subversion进行代码管理了。为了方便,你可以选择一个好用的GUI client,比如tortoisesvn等等。

第二,就是讨论一下如何进行你的web页面开发。
说实话,这个我现在还不熟悉。我还只是搞明白了如何在线编辑。
你可以使用一个SSH Client(例如PuTTY)连接 shell.sourceforge.net,用你sf的用户名和密码登陆,这个时候你是进入到你自己的home里面(/home/username),你的web page是放在/home/groups/project_directory/htdocs(例如/home/groups/k/ku/kuteedit/htdocs)。

SourceForge使用的是Apache 1.3.3和php 4.1.3,你能使用的Editor是vi和emacs。现在你就可以进行web page的编辑了。
其实是可以上传文件的,但是我还没有研究明白,等我明白了,再分享给大家。

2006-05-19

由于工作的需要,我现在开始接触php了,以前一直没有任何php的经验,在我的感觉里面,还存留着php好像asp的看法。其实发现是不对di~~~。

我用的是php5,感觉用起来很爽。用习惯了javascript的面向对象,php的面向对象理解起来很简单(没有和java比较,是因为我觉得还是有一些区别,至少php是松散的(我的理解))。

这两天看的是plog,一个blog系统,现在改名子叫做lifetype,是一个很简单的blog系统,但是他里面的代码层次写的非常好。是一个典型的MVC的框架,很容易理解,加上他使用了页面模板(template)smarty,让我这个有java MVC思想,用过strutsfreemarker的人,理解起来很容易。用了3小时,就搞明白了他的层次结构,顺便还学了个php的面向对象。

这里就想到了,lifetype还有smarty用到的很多的思想都是和java一样的。我无法确认哪个实现的更早(但是我觉得应该是java的struts,freemarker等等更早),但是重点是思想而不是语言。这句话我总说,但是由于还是经常用java,而js又不是一个服务器框架级别的语言,所以体会不深。这次算是真的体会到了,虽然我看lifetype的时候,连php的全局变量怎么使用都不知道,但是我还是在极短的时间里面掌握的lifetype。可见思想的重要性(开玩笑的说就是设计文档比代码难写多了)。
愈以为,Java之所以现在受到推崇,就是他能够屏蔽很多的细节,让设计者更加专注的去研究框架体系。所以Java世界出现了很多指导意义的思想,框架等等。当然了,因为Java世界有牛人,就说因为自己学java就是牛人的人嘛……算了,不说他们什么了,真给Javaer丢脸(貌似这种人在国内还很多)。
今天又找了一个php的unit test工具,simpletest,据他自己说,是一个比phpunit好的东西,由于我没用过phpunit(废话,刚接触php不过三天),所以选择了simpletest。其实让我选择他的很重要的一个原因,就是simpletest是一个还活跃的项目,而phpunit已经好几年没有更新了。可见一个项目的活跃程度的重要性。

呵呵,好了,这就是我对php的一些初步的印象。总体感觉非常好,但是肯定无法得到100分,原因嘛,很重要的就是他一堆烦人的$(php的作者是不是想钱想疯了?)

2006-05-13

停了一段时间,今天说说JavaScript的面向对象
js不是一个天生的oo的语言。但是他的函数是可以担负面向对象的概念的。并且js也内置了很多的对象,比如String,Date等等。

js有一个关键字new,可以认为是实例化一个function的对象,把function作为一个class。
比如
function MyObj () {
}
var myObj = new MyObj();
这个时候,myObj就是MyObj的一个实例。

有两点应该具体的说一下
1,JavaScript是一个prototype的语言
2,this在JavaScript里面的应用

首先我们说一下prototype,prototype是一个function的属性,也可以认为是一个类的属性。他用来记录这个类有那些方法。
比如我们要给MyObj定义一个sayHello的方法,我们可以这样写
MyObj.prototype.sayHello = function () {
alert(”Hello”);
}
这个时候,我们就可以调用myObj.sayHello()执行这个方法。

而this则表示这个类本身(严格意义上说,应该是这个函数本身),比如
MyObj.prototype.sayBye = function () {
alert(”bye” + this.name);
}
那么这里的this,就是实例变量本身。myObj.sayBye()。函数里面的this就是表示myObj。那么我们就可以实现带参数的构造函数。

function MyObj2(name) {
this.name = name;
}
var myO2 = new MyObj2(”tom”);
这样,我们就可以实现一般情况下使用的面向对象了。

需 要主意的是,JavaScript没有属性的共有私有机制,我们可以通过myO2.name访问他的name属性。而且js也不是强行规定的,我们要访问 myO2.age也是可以的,但是myO2并没有age的属性(或者说重来没有给age赋值)那么得到的就是undefined。
通过这个,我们就可以用Object来实现平常使用的Map(java语言,对于python应该是字典类型)。
var m = new Object();
m["name"] = “tom”;
m["age"] = 20;
alert(m["name"]);
注1:对于alert,JavaScript调用的是这个object的toString函数,如果没有,则会显示 ie:[object] ff:[object, Object]
注2:在js当中,new Object和{}是一样的,我们可以写 var m = {};
这也是js中简单的map的实现。不好的地方是遍历不方便,因为没有地方记录有那些key
for (var i in m) 这种遍历方法,会把所有的对于object进行扩展的方法都显示出来。

对Object的扩展,是通过对Object的prototype添加方法实现的。
比如js的String方法是没有trim的,我们可以自己做一个实现然后通过扩展String来提供这个方法
String.prototype.trim = function () {}
var a = ” 123 “.trim();

上面提到了一下this,之所以说一下this,是因为他并不完全等同于C++或者Java里面的this变量。
this在js中表示紧贴着调用地点的,非prototype扩展的方法。
比如上面提到的
MyObj.prototype.sayBye = function () {
alert(”Bye” + this.name);
}
这个里面的this,紧贴的非prototype的函数是MyObj(再次注意,js中class是通过函数实现的),所以this.name就是实例变量。
但是在这种情况
MyObj.prototype.doSomething = function () {
todo(function () {
alert(this.name);
});
}
这个时候,this表示的是这个匿名函数
function () {
alert(this.name)
}
那么这里就会出现错误,如果想要这样使用,应该使用辅助变量。
MyObj.prototype.doSomething = function () {
var me = this; //把自己的reference赋值给变量me
todo (function () {
alert(me.name); //通过me来访问myObj实例
});
}
而且所有的实例变量必须通过this来进行访问,直接写变量名称会认为是全局的变量。
上例中的alert(this.name)是正确的,而alert(name)是错误的。

还有最后说一下静态方法。我们可以用js来模拟静态方法(或者说是类方法)
就是直接把方法写在函数上
MyObj.staticMethod = function () {
}
这种方法都是实例无关的,调用的时候,通过MyObj.staticMethod()来调用。其实这也是一个变通的方法。

下一次我再说说类的继承。
大家有什么想要听的,告诉我,如果我会,那么我一定分享出来。

今天说一下函数参数。

函数参数,可以理解为函数的参数,还有就是函数作为参数(还是挺诡意)。
首先说一下函数的参数。
这个问题看上去没有什么可说的。因为作为拍代码的,都肯定知道这个东西。
function method1(a, b) {
return a + b;
}
很简单,a,b就是函数method1的参数。一般情况下,这样足够了。
但是在JavaScript当中,函数的调用,其中的参数个数是不强制的。(作为脚本语言,当然类型也没有强制)。
这里很象某些语言的不定参数列表(由于我没有过多的研究,所以不便多说)。
比如上面的方法
var c = method1(1,2); //正确
var d = method(1); //也正确
此时c的值是3,d的值是NaN。
那么我们如何来保证参数的个数呢?
JavaScript当中,每一个方法里面,有一个内欠的变量,arguments。这是一个数组变量,记录着传入这个方法一共有几个参数。
很象java里面main函数的 args数组
static public void main(String args[]) {…}
我们可以使用arguments.length来判断一共有几个参数
function method2() {
if (arguments.length == 2) {
return arguments[0] + arguments[1];
} else {
return 0;
}
}
这样我们就可以保证参数的个数了。

接下来,我们说一下函数作为参数。
在昨天的例子当中,我使用了很多这样的例子。比如
ServerHandler.getName(myID, fucntion (name) {
alert(”Hello:” + name);
});
这里面,getName方法的第二个参数就是一个方法,
function (name) {…}
在JavaScript 当中,任何的东西都是Object,一个函数的类型是Function,他是Object的一个子类(姑且这么说,JavaScript不是一个纯粹的面 向对象的语言,所以说子类有一些牵强)。所有的Object都可以作为参数被传入函数。那么一个函数作为参数就不足为奇了。

暂停一下,我们现来看一下这个例子。
function method3() {
alert(”Hello”);
}

var m = method1;
var v = method1();
上面的两个变量,m,v,他们的区别就是,v是method1运算的结果,在这里是undefined,因为method3在alert以后什么都没有返回。
而m,这句付值语句,是把method3的函数体,付值给了m(有兴趣的话,可以使用alert(m)来看一下结果)。如果现在写下如下的语句
m();
那么就会调用这个函数,然后alert一个Hello。

好,我们回来,上面我想说明的就是,当一个函数作为参数传入到另外的一个函数当中,我们是可以使用一个参数变量来接受这个函数的。并且在需要的时候,我们可以继续的分发,或者调用。
比如
function method4(m) {
m();
}

method4(method3); //注意,这里面的method3没有后面的括号(),他表示是这个函数体作为参数而不是运行结果作为参数。
在进入到method4里面之后,通过参数变量m,可以调用method3。

利 用函数作为参数,在JavaScript中使用的最普遍的就是callback方法了。当需要执行一个函数,传入一个callback function用来处理结果。这种方法我们在很多地方已经使用的非常多了。现在随着AJAX的流行,callback方法也越来的重要。如我昨天所说, 很多的和server通讯的方法都是无法预料何时能够结束的。那么传入一个callback function就很方便了。

这里,我一直有这样的一个难点,始终没有很好的解决办法。
就是一般情况,我们给出callback function,都是在无法控制返回时间的情况下采用的,那么此时,大多数的情况就是这个方法会使用另外的线程来执行,而程序会继续向下走。
使用返回值的函数调用,是会在这个函数调用的时候,线程阻塞,直到返回结果。
我现在遇到的情况就是,很多的时候,我无法返回值(比如AJAX),而使用callback function也挺麻烦。所以一直没有好的方法。
虽然我昨天说的信号量的方法可以变通的解决这个问题。但是在复杂的情况下(比如我现在正在开发的一套Web UI Framework)里面也是挺麻烦的。希望大家如果有好的方法可以告诉我。

最后,还要提及的一点就是,在函数调用的时候,还有一种方法就是call(或者apply)调用。
function method5(msg) {
alert(msg);
}
method5.call(x, “Hello”);
这个x就是某个Object的变量(从面向对象的角度可以说是一个实例(instance))。很类似于python的self。
这个使用方法在一般情况下意义不大。但是在某种面向对象实现的时候是非常有用的。我会在面向对象的文章中再次说明的。

从今天开始,我会不定期的写一些关于JavaScript的东西,包括语言,应用等方面。组成JavaScript系列。
如果没有特殊的说明,这里假定JavaScript的执行环境是在浏览器(browser)当中的。
今天开始第一次,讨论一下同步和异步。

曾经查询过一些JavaScript的信息,发现google出来的结果都是询问JavaScript如何能够实现异步的代码。
而我,很不幸,查询的却是如何让JavaScript实现异步调用的同步(是不是挺起来很诡异)。

首先说一下JavaScript当中的异步方法。
其实这个问题是大家经常要碰到的。而且这个实现也很简单。我就不多说了。
给两段代码

  1. setTimeout方法,他让你的代码在指定的时间(毫秒)之后执行指定的方法。只执行一次。
    比如:
    alert(1);
    setTimeout(”alert(2)”, 1000);
    alert(3);
    代码在执行到setTimeout的时候,会继续执行下面的代码(alert(3))而不会被阻塞。等待1000ms之后执行alert(2)
  2. setInterval方法,他让你的代码每隔指定的时间,执行指定的方法,直到调用clearInterval
    比如:
    alert(1);
    timer = setInterval(”alert(2)”, 1000);
    alert(3);
    代码基本上和上面的相同,不同的是,每隔1000ms就会执行一次alert(2),直到调用
    clearInterval(timer);

我们应该注意到setTimeout和setInterval都是window的方法。
我们可以直接使用,但是规范的还是调用window.setTimeout window.setInterval,之所以提及这个,我会在以后的JavaScript系列中继续讲解。

现在该说一下我遇到的问题了。
我现在使用dwr作为AJAX的server端引擎,在调用dwr方法的时候,需要提供一个回调方法(callback function)来接受server的返回结果。
而这个回调方法是不会被阻塞的。此时browser回启动另外的现成处理。
这个很好理解,因为dwr的这个方法执行的时间是无法预料的,如果此时调用被阻塞,而server又花相当长的时间进行处理。那么浏览器就会死在这里。从用户体验的角度是根本无法接受的。
这里的例子代码是


ServerHandler.getString(”Weiming”, function (str) { //”Weiming”是传回server的参数
alert(str);
}); // ServerHandler是dwr提供的server方法的interface,具体使用请参见dwr网站。
alert(1);
在执行的过程中,会先执行alert(1),然后在一个无法预料的时间后执行alert(str)。
如果一次简单的比如hello world的调用是不会出问题的。
但是如果我要执行的一系列的dwr function是有前后顺序的,比如后面执行的需要前面的返回结果,简单的代码书写顺序是无法保证执行顺序的。
var myID = null;
ServerHandler.getID(function (id) {
myID = id; //无法预料何时会执行这句话
});

ServerHandler.getUserWithID(myID, function (name) {
/*
此时myID还没有值,因为上面的 myID = id这段代码是需要一个时间段之后才会执行的
*/
alert(”hello:” + name);
});

比如这样的代码就会出错。那么如何解决呢?
最简单的实现方法就是callback function的嵌套。

ServerHandler.getID(function (id) {
ServerHandler.getUserWithID(id, function (name) {
alert(”hello:” + name);
}
});
这样我们就可以保证多个dwr方法调用的顺序了。这样貌似解决了问题。但是并不完美。
原因是当我们把JavaScript和Browser作为一个操作的平台和逻辑业务的平台(AJAX的应用程序,后面的JavaScript系列中会有提及),而不是一个简单的展示平台的时候。这样的回调函数嵌套就很难控制了。
这也就是我最开始指出的需要同步异步调用的一个方法。

最终我在公司的解决方案是这样的。
写一个信号量的类(JavaScript的面向对象会稍后讲解),当我需要执行一个方法的时候,我就申请一部分信号量。
把需要被执行的方法放进信号量的队列进行等待。等前面等待的方法(如果存在)执行后在执行。
信号量将作为一个参数被传入执行的方法,这样这个方法可以决定释放这个信号量还是继续分发。
比如
var s = new Semaphore();
var myID = null;
s.p(function (e) {  //把方法放入信号量队列
ServerHandler.getID(function (id) {
myID = id;
s.v(); //释放信号量
}
});

s.p(function (e) { //将第二个方法放到信号量队列,只有当前面的s.v()执行之后,这个方法才会执行。
ServerHandler.getName(myID, function (name) { //此时,可以保证myID一定有值
alert(”Hello:” + name);
s.v();
})
})

这里只是对信号量这个方法进行了简单的阐述。
信号量还支持创建自信号量,如果创建了子信号量,那么父信号量必须等带所有的孩子都归还了信号量之后才可以执行他里面的代码。
由于代码的版权是公司的,所以很抱歉,现在无法给出相应的完整的信号量的实现。
如果下一端我有时间的话,我会给出一个我实现的版本的。

Weiming – 央行又调息了 说:
对啊,给你看一个东西
Weiming – 央行又调息了 说:
http://www.fluxcorp.com
这个东西,我看了一下,感觉很不错
Weiming – 央行又调息了 说:
如果有时间,做一个,呵呵,和xxx竞争
PastHERO 说:
这个是免费的吗
PastHERO 说:
我觉得 engine 免费,然后就靠 sln 赚钱
Weiming – 央行又调息了 说:
不是,30天试用
Weiming – 央行又调息了 说:
是,我也是这么想的
Weiming – 央行又调息了 说:
现在国内没有做engine的,本来xxx有这个可能,但是被毁了
PastHERO 说:
所以就做一个像微软那样的轻便的 engin
PastHERO 说:
engine
Weiming – 央行又调息了 说:
是,然后卖solution
Weiming – 央行又调息了 说:
等engine完善了,再卖engine的license
PastHERO 说:
小到可以内嵌在一个小程序里面
PastHERO 说:
现在卖 license 已经不是好办法了
Weiming – 央行又调息了 说:
我得意思是,吧license卖给二次开发商
PastHERO 说:
就应该像 office live 一样,一年多少钱,我给你开帐户,你用就是了
PastHERO 说:

Weiming – 央行又调息了 说:
要不怎么去赚钱啊
PastHERO 说:
就是授权
Weiming – 央行又调息了 说:

Weiming – 央行又调息了 说:
就好像卖游戏的引擎
PastHERO 说:
没错
Weiming – 央行又调息了 说:
自己还能做,最后直接就只做engine就好了
PastHERO 说:
不过像微软的 engine 其实就是免费的吗
Weiming – 央行又调息了 说:
不能和微软比
Weiming – 央行又调息了 说:
微软真正赚钱的产品很少啊
Weiming – 央行又调息了 说:
好像只有windows还有office吧
Weiming – 央行又调息了 说:
其他的都是免费或者干脆赔钱,比如xbox
PastHERO 说:
对呀
Weiming – 央行又调息了 说:
所以她能免费这个engine
PastHERO 说:
哈哈
Weiming – 央行又调息了 说:
但是咱们不能啊,要不喝西北风了
PastHERO 说:
其实就做一微软那样的 engine 应该是挺容易的
Weiming – 央行又调息了 说:
wfmc.org
PastHERO 说:
它只需要处理流程和状态,不携带数据
Weiming – 央行又调息了 说:
这个是规范
PastHERO 说:
这个还有规范,晕
Weiming – 央行又调息了 说:
是,不携带数据
Weiming – 央行又调息了 说:
嘿嘿,是啊
PastHERO 说:
你周一过去
Weiming – 央行又调息了 说:
是,本来和她说,能不能早一点过去
Weiming – 央行又调息了 说:
但是她说,不行,最好还是周一过去
Weiming – 央行又调息了 说:
看样子,还有好几个人呢
PastHERO 说:
呵呵
PastHERO 说:
那就在家好好歇着呗
PastHERO 说:
都干什么了
Weiming – 央行又调息了 说:
睡觉,看电视,游戏
Weiming – 央行又调息了 说:
呵呵
Weiming – 央行又调息了 说:
还有就是安装了n次linux
PastHERO 说:
赫赫
Weiming – 央行又调息了 说:
基本上都荒废了
PastHERO 说:
一些者就不想干活了
Weiming – 央行又调息了 说:
对,而且也是一直调整状态呢
Weiming – 央行又调息了 说:
发现越休息,越累
PastHERO 说:
对,就是歇懒了
Weiming – 央行又调息了 说:
是,而且,对未来有一点迷惘了
Weiming – 央行又调息了 说:
觉得是不是,等一段时间以后,需要转型
PastHERO 说:
转什么型,那边又告诉你做什么吗
Weiming – 央行又调息了 说:
没有
Weiming – 央行又调息了 说:
我一直再想
Weiming – 央行又调息了 说:
做技术的,其实和盖房子堆砖头的,没什么区别
Weiming – 央行又调息了 说:
qihoo,面试我的时候,就一直说,看我的样子,不是一直做技术的
Weiming – 央行又调息了 说:
他们也说
Weiming – 央行又调息了 说:
做技术-》技术专家-》技术管理
Weiming – 央行又调息了 说:
说这个是适合我的
Weiming – 央行又调息了 说:
所以我肯定会有一些想法
Weiming – 央行又调息了 说:
现在的中国
Weiming – 央行又调息了 说:
其实是劳动密集型的
Weiming – 央行又调息了 说:
http://blog.donews.com/keso/archive/2006/05/11/864043.aspx
Weiming – 央行又调息了 说:
对于一个非技术密集型的企业,技术是没有出头之日的
Weiming – 央行又调息了 说:
因为劳动密集型,她不会多养好多的技术人员(我说的咱们理解的顶尖的人)
Weiming – 央行又调息了 说:
他们只需要1个独当一面的+100个会拍代码的
Weiming – 央行又调息了 说:
这样就能够发展起来
Weiming – 央行又调息了 说:
对于hansky
Weiming – 央行又调息了 说:
开始我认为是一个技术型的公司
Weiming – 央行又调息了 说:
可是从现在的发展来看,cpw就已经不是一个考技术吃饭的产品了
PastHERO 说:

Weiming – 央行又调息了 说:
虽然很多的很cool的技术,但是他们都是一种辅助的角度出现的,就算没有也无所谓
Weiming – 央行又调息了 说:
哪怕最落后的html+servlet也能把cpw做出来,而且做的很好
PastHERO 说:
包括整个 it 产业都不是一个以技术吃饭的产业了我觉得
Weiming – 央行又调息了 说:

Weiming – 央行又调息了 说:
hansky走到这一步,我觉得有可能是公司决策的问题
Weiming – 央行又调息了 说:
也有可能是市场的问题
Weiming – 央行又调息了 说:
也就是,这个市场,很少有技术密集型的企业能够活下来
Weiming – 央行又调息了 说:
比如google
Weiming – 央行又调息了 说:
比如cygnus
PastHERO 说:
现在,尤其 web 2.0 就是一个想法和把想法卖出去的问题
Weiming – 央行又调息了 说:
比如(假如)微软
Weiming – 央行又调息了 说:
是,
Weiming – 央行又调息了 说:
所以我想,如果想做出来,是不是不能只关心技术了,
PastHERO 说:
对 cygnus 的神话已经不存在了
Weiming – 央行又调息了 说:
或者干脆技术已经死了,等他爆发的时候,也许是下一(几)个十年
PastHERO 说:
现在的 it 跟 19 世纪末的物理学一样,经典的基础都被奠定的差不多了
Weiming – 央行又调息了 说:
需要一个相当长的时间才能爆发。
Weiming – 央行又调息了 说:
没有技术不行,可是全是技术,估计也就离死不远了。
PastHERO 说:
只剩下一些边边角角的东西了,需要等待像相对论和量子物理一样的冲击,就像编译器,关系型数据库等等
Weiming – 央行又调息了 说:

PastHERO 说:
目前这样的眉目还没有出现
Weiming – 央行又调息了 说:
或者说,只有某一个领域的纵向的东西,可以考技术吃饭
Weiming – 央行又调息了 说:
而这个只能是整个行业的,一点点
Weiming – 央行又调息了 说:
而且绝对不是面向大众的
PastHERO 说:
嗯,但是 it 还是一个工程技术而不是理论科学,所以深度的研究是要为产出作贡献的
PastHERO 说:
所以真正的技术也只有在微软研究院那样的地方才会出现
Weiming – 央行又调息了 说:
对,但是深度研究是有代价的
Weiming – 央行又调息了 说:
必须靠钱拍出来
Weiming – 央行又调息了 说:
人可以不吃饭,但是没设备就什么都出不来
Weiming – 央行又调息了 说:
一台只能跑dos的破机器研究出来web2.0的框架是不大现实的
Weiming – 央行又调息了 说:
除了微软,google,还有哪能(舍得)出这笔钱呢
PastHERO 说:
对呀
Weiming – 央行又调息了 说:
所以,做技术,不是不好,时候未到而已