庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

    读《Perl语言入门》(第四版,我买的书,网上有个翻译质量很高的电子版)的第10章的习题,人见人爱的猜数游戏,用perl写出来大概这样:
$num=int (1 + rand 100);
print "I have a number,guess it?:\n";
while(<>)
{
    
chomp;
    
next unless /\d+/;
    
$_>$num? print "Too high\n" :
        
$_==$num? last :print "Too low\n"
}
   题外话:玩Perl的高人们别鄙视我,我是perl新手啊,如果写的不够“perl”,多多指点。
  
   这段代码转成ruby,可以这样写:

$num=1+(rand 100)
puts 
"I have a number guess it?"
while(true)
   gets.chomp
   next unless 
~/\d+/
     $_.to_i
>$num?begin print "Too high\n" end:
       $_.to_i
==$num? begin break end:begin print "Too low\n" end
    
end

    看出来了吧,两者何其相似啊,包括perl里面人见人爱的$_,ruby也是支持的,唯一那么一点不同的地方就是last换成了break,然后是正则表达式左边多了个~,你完全可以将这个符号去掉,不过会有警告,最后就是Ruby中的要执行的表达式得放在begin...end里面,这一点让我琢磨了一段时间,还以为Ruby不支持呢。读《Perl语言入门》最大的乐趣除了妙趣横生的语言、古灵精怪的符号之外,就是寻找Ruby中的Perl痕迹,哦哦,那个味道相当重——骆驼的味道。不过现在Ruby不鼓励这样的写法,毕竟,程序是给人读的,因此可以改写一下:
$num=1+(rand 100)
puts "I have a number guess it?"
while(true)
   guess
=STDIN.gets
   next unless guess
=~/\d+/
   
if(guess.to_i>$num)
      puts 
"Too high"
   elsif(guess.to_i
==$num)
      
break
   
else
      puts 
"Too low"
   end
end

posted @ 2007-12-07 16:30 dennis 阅读(2206) | 评论 (1)编辑 收藏

    先是读《Programming in Lua》第9章讲coroutine,然后去google coroutine,找到Simon Tatham写的一篇coroutine in c,讲怎么在C语言中实现coroutine,文中先ugly地基于栈实现了一个:
int function(void) {
    
static int i, state = 0;
    
switch (state) {
        
case 0goto LABEL0;
        
case 1goto LABEL1;
    }
    LABEL0: 
/* start of function */
    
for (i = 0; i < 10; i++) {
        state 
= 1/* so we will come back to LABEL1 */
        
return i;
        LABEL1:; 
/* resume control straight after the return */
    }
}

这个方法简单,但是相当丑陋,你必须手工维护这些标签。然后提到了Duff's Device技巧:
switch (count % 8) {
        
case 0:        do {  *to = *from++;
        
case 7:              *to = *from++;
        
case 6:              *to = *from++;
        
case 5:              *to = *from++;
        
case 4:              *to = *from++;
        
case 3:              *to = *from++;
        
case 2:              *to = *from++;
        
case 1:              *to = *from++;
                       } 
while ((count -= 8> 0);
    }

这段代码能编译通过吗?能的,不信你试试,这是一段用于拷贝数组的代码,我们一般拷贝数组是这样做的:
send(to, from, count)
        register 
short *to, *from;
        register count;
        {
                
do
                        
*to = *from++;
                
while(--count>0);
        }
如果循环的中的操作足够快,那么其实大部分时间都是浪费在判断循环条件上面的,而通过Duff's Device通过switch语句将要进行的连续循环操作的次数进行了预判(根据擦case语句的位置)然后依次执行,而不必每次都去进 行测试条件,从而加速循环。这个技巧怎么应用于实现更优雅的coroutine呢?看代码

int function(void) {
    
static int i, state = 0;
    
switch (state) {
        
case 0/* start of function */
        
for (i = 0; i < 10; i++) {
            state 
= 1/* so we will come back to "case 1" */
            
return i;
            
case 1:; /* resume control straight after the return */
        }
    }
}
更好的方式是使用宏:
#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define crFinish }
int function(void) {
    
static int i;
    crBegin;
    
for (i = 0; i < 10; i++)
        crReturn(
1, i);
    crFinish;
}



posted @ 2007-11-29 18:17 dennis 阅读(1165) | 评论 (0)编辑 收藏

1.起点,经典hello world:

print("Hello World")

这与大多数脚本语言没什么两样,总体来说如果你对JavaScript、Ruby、Python之类有所学习的话,LUA还是相当简单的

2.函数定义,类似JS,用begin end代替大括号:

function fact (n)

    if n == 0 then

       return 1

    else

       return n * fact(n-1)

    end

end


function其实就是lambda算子.

3.  8种基本类型:
nilbooleannumberstringuserdatafunctionthreadtable

boolean类型除了false和nil是false之外,其他都是true
lua支持函数式编程,因此函数是一等公民,userdata用于存储C语言的数据,待深入。thread与多线程编程有关。table是lua的基本数据结构,是array和hash的综合体,比较奇怪的是默认索引从1开始,而不是通常的0。看例子:

days = {"Sunday", "Monday", "Tuesday", "Wednesday",

              "Thursday", "Friday", "Saturday"}

w = {x=0, y=0, label="console"}


4. lua与ruby一样支持多重赋值和函数可以返回多个值,常见控制结构没有什么好说的。

5.可变参数,lua有很浓重的C味道,可变参数也与C一样,用...表示:
function g (a, b, ...) ... end

也可以通过表来传递命名参数:

rename{old="temp.lua", new="temp1.lua"}


6.局部变量的声明 local i=0,仅在声明的代码块内有效。如果没有声明为local,将自动成为全局变量,一个变量在赋值前是nil,通过将变量声明为nil可以删除该变量

7.LUA是有尾递归优化的,也提供了各种高阶函数以及闭包等等特性。

8.loadstring函数,一般其他解释语言中的eval函数相似,不过他是返回一个chunk(每个chunk都是匿名函数)让你执行,比如

f = loadstring("local a = 10; return a + 20")

print(f())        --> 30

也可以通过loadfile将整个文件载入作为chunk。

9.require,用于加载文件,会搜索环境变量LUA_PATH设定的路径,同时能判断文件是否已经加载来避免重复加载。比较奇特的是路径的设置,与一般的路径完全不同,其实就是用?当占位符,然后require filename的时候,用filename代替这些文号,比如:

?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua

当你require 'lili'的时候,就会寻找下列路径的文件:

lili

lili.lua

c:\windows\lili

/usr/local/lua/lili/lili.lua


10.lua通过loadlib函数可以加载动态链接库

11.pcall在保护模式(protected mode)下执行函数内容,同时捕获所有的异常和错误。若一切正常,pcall返回true以及“被执行函数”的返回值;否则返回nil和错误信息。

12.

posted @ 2007-11-29 16:05 dennis 阅读(2560) | 评论 (0)编辑 收藏

    客户要求从Internet上的网页上抽取一定的数据,用来显示或者其他用户,这个需求很常见。这两天我们也遇到了这个需求,本来我一开始想是试用正则表达式去匹配需要的文本数据,后来经验丰富的经理给出了一个更好的思路,就是使用jtidy将不符合xhtml的HTML文件转化成标准的xhtml文件——本质上就是XML文件,然后利用xsl抽取并转换成我们所需要的数据的一定格式的xml文件。这样做其实就是将XSL模板当正则表达式来用,不过更清晰,当网页改变时也不需要重新编译代码,仅仅修改XSL模板就够了。过程如下:
     html->xhtml--xsl-->数据xml

    做的过程中,初次使用了xsl,xpath等技术,网上找了不少好资料,共享下:
jtidy: 

思路来源
http://www.ibm.com/developerworks/cn/xml/x-wbdm/

项目地址
http://jtidy.sourceforge.net/

参考,解决中文问题使用
http://www.blogjava.net/jhengfei/archive/2006/03/25/37312.html

xsl,非常系统教程和实践:

http://www.cnblogs.com/goody9807/category/36016.html

xpath:

http://www.yesky.com/201/171201.shtml


posted @ 2007-11-22 12:35 dennis 阅读(1149) | 评论 (1)编辑 收藏

    《人工智能的未来》的作者是Jeff Hawkins,也就是著名的PalmPilot掌上电脑和Treo智能电话的发明人,这牛人从小就对人工智能充满兴趣并孜孜追求,哪怕从事软件业也是为了自己的理想。就书的内容来说,很有意思。作者先批判了传统的人工智能的发展方向,并且断定传统的人工智能永远没办法造出能够与人脑相媲美的智能机器。因为想要真正地了解智能是什么,只有去研究人脑的智能,而不能单纯地依靠程序和数学。
    接下来,Jeff Hawkins系统地探讨了自己对于新大脑皮层的理论,也就是他所宣称的智能理论。所谓智能,其实就是新大脑皮层基于记忆-预测系统的系统体系。新大脑皮层由层次性的神经元组成,由人类在成长生活过程中不断记忆强化的各种“恒定表征”,以及由此对输入产生从上而下的预测。这样说太抽象,举个例子,你看着某个人的眼睛,这些信息通过你的眼睛感官上传到大脑皮层,由下而上,细节构成整体,过去的记忆形成的关于|“眼睛”的模式让你知道你看到的是眼睛。这个过程不是单向的,同时,你的大脑皮层作出预测,“哦,往下看我应该可以看到这个人的鼻子,往上看应该是额头”这样的预测从上往下传递,并且配合你的感官器官得以验证。所谓智能就是这样一个不断验证记忆中的“模式”(或者称为“恒定表征|”)不断作出预测的过程。
    那么,什么是意识呢?意识包括两种:自我意识和可感知的意识。我们通常所说的意识其实都是指自我意识,这种“意识”本质上也是基于记忆-预测模型的陈述性记忆。例如,昨天你去郊外参加野营,假设我有这么一种方法可以抹去你某一段时间的记忆,那么当你今天早上醒来之前,我运用这个方法抹去你昨天去野营的记忆。今天,昨天与你去野营的人说,“HI,昨天我们一起去野营了”,可是你已经没有这段记忆,你会很惊讶并且辩解说自己根本没有去,别人后来拿出了一起去野营的录象,你看了之后也许就说“啊,那时候我是没有意识的,我像个僵尸,我真的去了吗?”,可见,所谓自我意识就是陈述性的记忆。可感知的意识,比如我们通常认为蓝色代表忧郁,红色表示愤怒,这样的意识与古脑有关(古脑控制了人类的基本情绪和感受,性欲、饥饿、高兴等等),作者没有给出确切的解释,不过显然也与记忆-预测模型相关,我猜测这与人类长期进化形成的“记忆”有关。
    那么,什么是创造力?创造力在某些人眼里是那么的神奇,其实所谓创造力,仍然是构建在记忆-预测的模型基础上。我们俗语说“一通百通”,其实就是创造力的一种体现,精通一样技艺之后,在你的新大脑皮层已经稳定地形成了关于这项技艺的方方面面的“模式”,当遇到另一样需要学习的技艺时,专家们总可以找到两者间的共同点。比如在编程领域,设计模式就是关于软件的高级抽象模式,这样的模式可以应用于各式各样的语言。天才们的共同特点就是比一般人更能去发现抽象之抽象、模式之模式。因此,创造力完全是可以培养的,尽管由于个体上的差异(大脑的构造和大脑皮层的面积以及环境、信仰等等),但是每个人其实都可以去培养自己的创造力。遇到难题,首先不能放弃,很多人其实没有开始就放弃了,其次,应该从不同角度去考虑问题,应用不同感官和视角,这样可以激发起你对相似场景的模式记忆,类比而去解决问题。在科学史上通过类比而创新的例子举不胜举。
    最后,什么是想象?新大脑皮层对输入的信息与长期训练形成的“恒定表征”相验证,同时不断地去预测,预测从皮层较高层次往下传递。如果将预测的传输方向倒转,也就是将预测作为输入,显然,这就是想象。想象其实就是策划,不断对行为产生的后果进行预测。心理暗示的作用也从这个意义上得到了验证。
    说说所谓“恒定表征”,这个概念其实类似于柏拉图哲学中的“理型”。我们怎么知道一只动物是马,而不是别的什么东西。按照柏拉图的说法,这就是我们将感官中看到的马,与心灵中“理型”的马进行类比而得出这是一只马的结论,“完美理型的马”拥有马的一切特征,是具体马的“形式”。而且柏拉图认为,“理型”是与生俱来的,来源于一个称为“理型的世界”。Jeff Hawkins所说的“恒定表征”与此类似,不过“恒定表征”并不是生来就有的,而是人在成长过程中不断记忆学习形成的稳定“模式”。还是以马为例,第一次看见这种动物,你并不知道这就是所谓马,然后有人告诉你这就是马,你记下了马的特征和场景,在以后的生活里这个记忆被不断地重复和强化,进而形成了关于马的“恒定表征”:马是四条腿的动物,如果不是的话,你也可以通过其他特征断定这可能是受伤了只剩三条腿的马;并且一般王子和大侠们也都喜欢骑白马......

    基于这套新的智能框架,Jeff Hawkins认为我们可以制造出真正的智能机器,而且这个领域也将成为下一个技术革命。制造出的智能机器不一定有人的表面特征,也就是机器人管家这样的幻想中的东西并不是智能机器的方向,智能机器将充分利用速度和记忆容量上的优势,在特定领域发挥惊人的作用,比如思考数学上的多维空间、天气预报等等。这本书可以让你一口气读完,翻译得也相当棒,相当地推荐。

posted @ 2007-11-18 22:22 dennis 阅读(649) | 评论 (0)编辑 收藏

    搬家到了福州,电视没搬上来,住的又是郊区,晚上空余的时间大增,读书时间由过去的一两个小时增长到整个晚上。请还在读研的兄弟帮忙在学校借了7本书,除了本《人工智能的未来》(这本挺有趣的),其他都是技术类,也知道自己的读书面现在太窄了,不是不想看闲书,可确实有很多东西计划着要去学,如果还停留在计划,我怀疑自己到底还会不会去读,比如龙书和unix shell编程。谈一下最近读的很有感觉的两本书。
    首先是〈网站重构〉,这真的是我第一次认真地去看一本web设计类的书。尽管一直是做WEB方面的开发,但是对于网页的设计和布局我从来没有系统地学习过,当然更不清楚为什么这样做以及这样做到底好不好。因为做的所谓企业应用(可以指定用户使用的浏览器版本),对于web标准我从来就没有认真关注过,也就在读js高级程序设计时了解了js在各种浏览器上的基本差异。如果你跟我一样,我强烈建议你看看〈网站重构〉,从书中我才知道自己写的网页代码是如此恶心,充斥着占用带宽的垃圾代码,没有考虑可用性和维护,更不用说麻烦的浏览器兼容问题。这还不是关键的,更关键的是这本书让你回到了HTML和XHTML被设计出来的本意:他们是用来表示网站结构的,而应该将元素的展现交给CSS。将结构和展现分离带来了代码量减少,带来了维护的便利,也带来了优秀的浏览器兼容效果。
    另外一本让我熬夜读的就是鼎鼎大名的龙书 ,跟国产的一本正经的教科书不同,这本书没有一大堆罗列的公式和术语,在第一章简单地对编译器介绍后,第二章立马用C语言实现了一个简单而又完整的编译器前端(将中缀算术表达式转化成后缀表达式),又介绍了抽象的基于栈的机器实现算术运算和条件循环表达式的基本原理。一口气读完前两章,你得承认,计算机类的书还是国外的好。读的时候我想起我过去用JAVA写的一个简单的逻辑表达式解析器,虽然简陋,但是也暗合书中这个前端的原理,没有系统学习过,写出来的也是野路子,有需要的话再改写一下。
   最后是工作,不是很顺利,没有我想像中的那么好,毕竟理想和现实是差距是永恒存在滴。开始一段时间挺不开心的,毕竟陌生的人和事总会让你有点找不着北。我想我会适应的,稳定下情绪,慢慢进入角色,做好本分就是了。   

posted @ 2007-11-17 21:19 dennis 阅读(554) | 评论 (2)编辑 收藏

    这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样的反模式也因为ajax的出现(异步加载)变的不是那么“反模式”了,其中又讲述了很多ejb的反模式,这些在轻量级框架流行的今天也早已经过时。不过书中有一个章节倒是挺有价值,讲述的是java的内存泄露问题,我认为是我目前读的关于这方面问题比较有价值的介绍。
    网上关于java内存泄露的资料都过于玄乎,其实java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。作者在书中提到了3个场景:
1。流失监听器问题,在awt、swing编程中,给组件添加了事件监听器,这些组件的生命周期如果很长的话,监听器对象将不能被正确回收。关于GUI编程我不是很熟悉,这一点存有疑问,因为显然你触发一个按钮的事件,当然是一直期待同样的行为发生,如果删除了监听器或者使用弱引用让JVM回收不符合业务逻辑和用户体验。

2。集合类,集合类仅仅有添加元素的方法,而没有相应的删除机制,导致内存被占用。这一点其实也不明确,这个集合类如果仅仅是局部变量,根本不会造成内存泄露,在方法栈退出后就没有引用了会被jvm正常回收。而如果这个集合类是全局性的变量(比如类中的静态属性,全局性的map等),那么没有相应的删除机制,很可能导致集合所占用的内存只增不减,因此提供这样的删除机制或者定期清除策略非常必要。

3。单例模式。不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:
class A{
    public A(){
           B.getInstance().setA(this);
   }
   ....
}
//B类采用单例模式
class B{
     private A a;
     private static B instance=new B();
     public B(){}
     public static B getInstance(){
         return instance;
    }
    public void setA(A a){
          this.a=a;
    }
   //getter...
}

显然B采用singleton模式,他持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较大的对象或者集合类型会发生什么情况。

    上面所讲的这些也启发我们如何去查找内存泄露问题,第一选择当然是利用工具,比如jprofiler,第二就是在代码复审的时候关注长生命周期对象:全局性的集合、单例模式的使用、类的static变量等等。

posted @ 2007-11-11 20:18 dennis 阅读(2870) | 评论 (4)编辑 收藏

    在Ruby中,无论类或者对象,都有一个singlton类(或者称为metaclass),有兴趣的话读读过去写的这篇《Ruby的对象模型》。当我们获取某个类或者对象的class属性时,其实会忽略c ruby层次上的singleton类,那么我们如何得到singleton类呢?比较有趣的做法:
singletonclass=class<<Test;self;end

对于对象,也是如此:
test=Test.new
metaclass=class<<test;self;end


posted @ 2007-10-31 11:33 dennis 阅读(335) | 评论 (0)编辑 收藏

    9月20号提的离职,按公司的要求,我也呆到了10月底,本来以为可以顺利离职,可中途公司又提出想调我去武汉的新项目组。按我的想法,还是想在省内再找家好点的公司锻炼两年,经过更多的项目锤炼,然后去北京、上海或者广州等地追寻新的梦想,因此拒绝了公司的提议。前天公司又额外生枝,要求我呆在11月5号,可我的离职明明写的是31号,公司有什么道理要求我呆到5号呢?自认为对工作也是尽职尽责了,为了交接工作的顺利进行,我还特意加班让接手工作的同事多点时间熟悉,我认为自己尽到了责任,因此向公司领导说明了我会在明天就离开公司。最后终于还是成了,明天先回家,然后去福州,新的工作已经找好,托了同学帮忙找房子,事情向好的一面发展,心情也好了不少。因为换工作带来的烦恼慢慢消逝,对未来还是充满信心。

posted @ 2007-10-31 10:46 dennis 阅读(656) | 评论 (5)编辑 收藏

     摘要: 在未来,我们可能需要的是一个个高效精干的小型团队,团队成员技艺高超,富于激情,易于沟通。  阅读全文

posted @ 2007-10-25 10:11 dennis 阅读(1165) | 评论 (4)编辑 收藏

仅列出标题
共56页: First 上一页 31 32 33 34 35 36 37 38 39 下一页 Last