• 04 八 2010 /  杂项

    很久之前就开始迷恋Texas Hold’em(德州扑克)这种游戏了,记得那时候是一个哥们看了007《皇家赌场》后,不断翻看电影片段总结出这个扑克游戏怎么玩的。然后由他,在一个漆黑的夜里拿着麻将当筹码教会我们怎么玩的。

    后来的日子里,我们玩得次数不多,但平时通过视频、网上包括观察一些其它人玩的牌局,逐渐觉得这东西根本就不是一个简单的赌博游戏,它完全是变化多样的、需要考虑很多方面的、需要胆识的一个竞技类运动。

    最近我们聚在一起玩的次数比较多,大家进步也很快,为了更好的提高自我,我开始寻找一些资料来研读,结果发现了更多的相关内容,下面罗列一些供日后参考。

    视频类

    《World Series of Poker》

    每年在美国拉斯维加斯举行的世界扑克锦标赛WSOP(World Series of Poker)已经成为了一项全球瞩目的娱乐盛典。WSOP组织者正在计划在欧洲进行《World Series of Poker 2008》赛事,首先计划于2007年9月6日至16日在英国进行三场比赛。WSOP组委会委员Jeffrey Pollack表示“这是我们向全球扩张的第一步,我想在以后的一年到三年内,我们会看到WSOP的比赛在全世界范围内进行。”同时他暗示可能包括在埃及和南非的Harrah’s赌场内进行比赛。WSOP于1970年开始举办,参赛选手已经从1978年的42人增加到去年的8773人。2007年WSOP 比赛已经又刷新了多项参赛人数记录。

    http://www.verycd.com/topics/2760748/

    《North American Poker Tour》

    北美扑克巡回赛(NAPT),由PokerStars.net主办,始于2010年1月,第一站在世界著名的都城拉斯维加斯及康涅狄格州。

    http://www.verycd.com/topics/2819986/

    《High Stakes Poker》

    High Stakes Poker德州扑克现金游戏电视直播节目由GSN副总裁Mike Bevan创立,当年在一个晚餐上,Johnny Chan告诉Mike Bevan 他输掉一个很大的底池给 Phil Ivey,使他意识到如果组织一场普通人难以承受的高注额德州扑克赛应该能吸引更多的观众,于是便创立了这个节目,如今High Stakes Poker已经是第五届了。

    http://www.verycd.com/topics/2801476/

    《Poker After Dark》

    Poker After Dark, NBC’s new late night show, invites viewers into the exclusive Las Vegas poker scene. The nightly hour-long show, hosted by LeeAnn Tweeden, features six poker professionals vying for a winner-take-all $120,000 first place prize.

    Hosted by Leeann Tweeden, each week’s tournament will follow the action from the time the players shuffle up and deal until the last pot is pushed to the winner. In between, you’ll see first-hand why the pros say it takes more than just good cards to be a winning player.

    Bluffs will be called, nerves will be tested, and characters judged as each player attempts to outplay, outwit, and outmaneuver the competition.

    When all is said and done, one player will walk away a winner while the rest will just walk away.

    http://www.verycd.com/topics/2788071/

    《National Heads-Up Poker Championship》

    国家单挑扑克锦标赛是美国NBC电视网举办的高规格扑克单挑锦标赛,是第一个在美国主要电视网进行转播的扑克赛事,每年一届的比赛吸引了众多职业扑克高手参加。

    The “National Heads-Up Poker Championship” is an annual event that pairs up 64 of the world’s greatest poker players in a heads-up one on one match-up for a prize of $500,000.00.

    http://www.verycd.com/topics/2815437/

    《The Poker Star》

    The Poker Star, pitched as Australia’s first ever poker reality series, premieres on ONE and TEN from September 30.

    2005 World Series of Poker champ Joe Hachem hosts the series that sees eleven Aussies compete against each other for the chance to win $100,000 and travel the world competing in the world’s largest tournaments as Joe Hachem’s protege.

    Contestants will dive with sharks, walk high wires and face off against Secret Service trained “Human Lie Detector” Steven van Aperen.

    Over eight weeks four female and seven male competitors have been living together in Melbourne and being filmed around the clock.

    Poker strategist Lee Nelson will help judge the contestants’ performance.

    The show ties in with an online poker site.

    A timeslot is yet to be confirmed.

    http://www.verycd.com/topics/2771981/

    《How to Make Money Playing Texas Hold’em Poker》

    http://www.verycd.com/topics/93763/

    书籍类

    大家最常推荐的有

    《Super System》Doyle Brunson

    《Super System 2》Doyle Brunson

    《The Theory of Poker》David Sklansky

    《Getting Start in Hold’em》Ed Miller

    《No Limit Hold ‘em Theory and Practice》 David Sklansky, Ed Miller

    网站类

    我常去的在线网站是Full Tilt Poker http://www.fulltiltpoker.com,其它著名的也有Poker Star,国内的站点因为不涉及到真钱,所以没有办法真实体现玩家的技巧,基本上就是什么牌都要All-in到底,因此不推荐。

    Tags: , ,

  • 10 六 2010 /  杂项

    ok,过两天水果公司就会让大家升级到iOS 4了,幸运的我现在用的是港行iPhone 3GS,碰巧没有破解,碰巧手里还有水果公司的开发者帐号,于是就刷新了我的iPhone,更新到iOS 4。本来想用别人的机器当个小白鼠,结果发现都有限制(锁机解锁版、破解了的),所以只能自宫了,幸运的是一切很顺利,成功上身了。

    新的功能自己体会才有意义

    1、屏幕主题

    原来不管怎么设置只是在解锁的时候才会有图,现在整个屏幕主题会在所有icon下面做为背景图出现,iPhone终于在不破解的情况下更加个性化了。解锁后所有图标是从屏幕四周飘到中间,也挺酷的。

    2、多任务

    这个东西是升级最大的动力,双击Home键会浮出来已经启动的应用是那些,应用之间可以随意切换了,遗憾的是,现在所有的应用都没有跟着升级,所以即使切换也没有效果,默认3.2的程序还是当做你重新启动的样子冒出来,期待iOS4正式发布的时候,所有的应用都升级了,这个功能就好玩了。不知道内存管理如何,如果过多程序在后台会不会死机,手动强制关闭应用的方法是长按应用图标,就会出现左上角带禁止符号的状态,这时候再按图标就会一个个关闭。手指往右滑动到头,还能有一个ipod的快捷控制面板,嘻嘻。不知道Home键的寿命如何,这功能增加了很多点击它的机会。

    3、文件夹

    一个图标可以变成一个文件夹放入更多的应用,一开始这个功能还不知道怎么玩,后来发现是在编辑图标的时候把一个图标拖到另外一个图标上,两个就能合并并且让你输入文件夹的名字,确认后就产生了文件夹,再放入新的图标就可以继续拖进去就可以了。

    4、邮件应用

    邮件首页可以看到全部的邮箱,并且把常用的收件箱可以合并一起看,省着一个个点击了

    5、相册

    支持一般浏览和事件浏览两种切换了,并且还有一种很酷的列表方式是按照地区列表,发现我以前用iPhone拍摄的照片都有保存经纬度,这样能够用大头针的形式显示出我在那个区域拍过照片,很是爽呀。

    6、位置

    当你使用位置数据的时候,开启gps或在应用中分享位置,右上角都会有一个图标显示你正在使用位置服务

    其它的我也没有试验这么多了,不是有1500多个改动,真不知道还有什么细节有变化,目前发现的问题是我以前导入的照片都变成特别虚的版本了,怀疑是需要重新同步,或者这是相册的bug?Anyway,正式版本很快就要出来了,耐心等待吧

    Tags: ,

  • 26 四 2010 /  杂项

    忙忙忙,没有忙里偷闲的时间,也就没有时间写东西,时间是挤出来的,看来我要认真挤一下!

  • 25 十一 2009 /  互联网技术

    昨天花了一下午的时间测试一个程序的执行效率,该程序是一个后台日志分析的程序,犯懒用php写的,毕竟php对文本处理效率很高(编写&执行),一开始担心php的数组按照键值查询效率低,所以使用memcache作为内存缓存来用。

    程序编写好后执行正常,当处理数据量上来以后,发现执行很慢。其它的项目中我也发现在压力测试时memcache会是瓶颈并导致很高的cpu占用,因此怀疑是否自己编译的php+memcached有问题,或者是其它问题。于是做了下面的测试。

    Trace for /logprocess/process_sessiontime_memcached.php
    Total Elapsed Time = 767.74
    Total System Time = 19.15
    Total User Time = 742.67

    Real User System secs/ cumm
    %Time (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name
    --------------------------------------------------------------------------------------
    69.2 531.12 531.12 520.74 520.74 6.94 6.94 92646 0.0057 0.0057 0 Memcached->set
    21.4 164.18 164.18 157.25 157.25 4.85 4.85 92646 0.0018 0.0018 0 Memcached->get

    从上面的数据能看出,这个程序php执行的瓶颈在memcache,而set操作更加有问题,接近70%的时间都在做set操作,难道真是使用的模块有问题嘛?我查过php的memcached模块,代码基本上就是一个连接,实质使用的还是libmemcached这个库的内容,所以如果要是有问题的话也肯定在libmemcached这个上面。但网上搜索后,无果,没有人说它有问题。

    后来细想,按照上面的数据折算,读写平均的话122.22次/秒,读单独是564.30次/秒,写单独是174.47次/秒,数据表现也算不错了。写慢是memcache以及被测试的程序逻辑有矛盾,我了解了一下,memcache会使用item(key+value)的长度做前期的定位,试想如果程序使得value长度不断变化,是否set会不断移动item所在的slab位置呢(将旧的变成过期,再按照新写入数据的流程写入新的item)?没有深度考究,但觉得值得怀疑;如果写操作所占用的cpu释放出来的话,读的效率应该可以更高,回头可以测试一下,估计能超过1千次/秒。

    总结上述,memcache使用要被仔细的规划,取长补短,如果随意使用的话未必能有好的效果。上面的程序其实就不应该用memcache,频繁的写不是memcache的强项,而分布式、多点频繁读取才是强项。

    说道缓存,所以我顺便又测试了Alternative PHP Cache(APC)的模式,还是刚才的程序,出来的结果是读写平均392.57次/秒,比memcache快3倍多,我没有出读写分离的数据,估计如果单读的话,应该还能再快一些,毕竟APC是本地缓存。因此,如果你的应用不需要分布式的话,APC是一个很好的选择,它能帮你在一台机器的情况下,保持并缓存每次php请求之间的数据。其次,它还是一个类似eAccelerator的代码opcode缓存模块,可以提高php代码执行速度。

    最后,回到我一开始没有考虑的解决方案,因为我不需要跟其它进程或者服务器共享我的数据,所以直接用php的数组,处理速度是多少呢?15,441次/秒!当然啦,内部就是一堆指针指来指去而已,我没有想到的是数组在很多无序的key中找value还是很快的,所以以后大家可以放心这么使用,只是注意配置文件中允许的php运行时占用的内存再调大点就好了。

    总结,任何设计要根据具体的应用需求来选择解决方案,选择时要考虑所选技术本身的特性,取其优点避其缺点。Memcache不适合做数据频繁变化的内存共享,一次写入多次读取的模式会更适合一些。Tokyo Tyrant / Tokyo Cabinet / Redis也许能用于频繁读写的情况,我还没有时间去评测;BTW,以前还使用Mysql内存表做这类事情多一点,希望能构建一个数据写入缓存机制,但是实际使用时还是有一些问题,所以有空再找找新的解决方案吧。

    最后说一句,就一句:在Memcache盛行的当今,Memcache不可滥用。

    Tags: , ,

  • 23 十一 2009 /  互联网技术

    脑子不好使,只能记录下来以后备用

    首先python有几个版本,我现在选择的是2.5版,版本越低,可选择的第三方支持包就越多,当然也要平衡,低版本也会有性能问题,或者小bug。2.6是3.0的过度版本,有很多新的特性但又兼容老的版本(3.0有些老版本的语法、特性就不支持了),所以权衡选择了2.5版。

    python自身的安装比较简单,在linux下就是通过源码编译就可以了,需要注意的是,python在linux系统下作为很底层的语言支持,通常系统会有一个版本默认已经安装了,如果你觉得那个版本够用就直接用,如果安装新的版本,最好不要改动或者覆盖那个版本。我一般都在/usr/local/python2.5目录下安装一个新的,然后ln -s /usr/local/python2.5/bin/python2.5 /usr/bin/python2.5,这样原有的版本和新的版本互不干扰。

    python的扩展包很多,一般分成两类,两种方法来安装
    1、扩展包是直接的源码包
    通常这种包解开后会有一个setup.py的文件,使用你希望安装这个扩展包的python版本来运行python setup.py install就可以完成安装,当然你也可以先python setup.py make再install,意思和linux下编译源代码的流程是类似的。

    2、.egg文件
    这种类似jar的代码包是一个叫easy_install的项目产生的,首先你可以下载并安装easy_install;如果你的easy_install是.egg结尾的,可以使用sh easy_install.egg来安装。如果是普通源码包就参考上面第一种方法安装。
    安装后会在 /bin/目录下多出来一个叫easy_install的脚本。你下载的.egg包就可以运行./easy_install xxx.egg来安装了。
    当然还有一个更简单的方法,就是./easy_install module_name,这样它就会在网上找到适当的模块进行自动安装并且保持模块之间的关联。
    easy_install除了网上查询包自动下载,后续的工作就是在 /lib/python2.5/site-packages/目录下的easy_install.pth文件中加入了.egg文件的关联而已,并且将.egg文件拷入上述这个目录,这样python在寻找软件包的时候就能找到并自动装载。

    BTW:有关Python MySQLdb模块
    上述安装方法很自然就可以将这个模块安装好,但是我的习惯不喜欢将mysql客户端的库放在默认的位置,导致实际python导入模块的时候会报错,这时候只需要将你的库文件路径加入/etc/ld.so.conf中,并且执行ldconfg -v就可以了。

    Tags:

  • 19 十一 2009 /  杂项

    over-working

    最近又听说有人因为工作劳累而驾鹤西游了,某公司危机公关忙得不亦乐乎,顿时觉得有点悲哀。

    记得Joel Spolsky在他的The Best Software Writing I这本书里面收录过一篇文章叫EA: The Human Story,主要内容是描述EA内部过渡加班的问题,并且用数字说明加班也许并不能提高工作效率,反而会降低工作效率,引发员工很多心理问题导致最后人员流失。

    个人认为公司不能将加班当做正常的一种工作手段,如果你在估算工作计划的时候就把加班考虑进去了,那你就丧失了所有缓冲时间;试想加班是计划的一部分的话,如果不能按照计划完成,你还有什么选择?

    人是有周期性的,长期在高度紧张的状态容易效率低下以及疲惫不堪,情绪会非常波动,整天只有身躯在办公室里坐着而思想不知道跑到那里去了,这样的表现公司是不愿意看到的,但老板通常会想念大家,希望7X24小时在公司能看到大家忙碌。停下来想一想,这样的效果好嘛?磨洋工对项目有意义嘛?

    在不能改变别人的情况下,你就需要自己注意,如果觉得累或者情绪不好,就干脆什么都停下来,休息,睡个觉,做点别的无关的事情,也许做着做着你就有新的工作思路以及冲动了。

    希望传闻的悲剧能被合理的解决,并且大家尽量避免悲剧的再度发生。

  • 27 十 2009 /  互联网技术

    原文链接:Nginx & Comet: Low Latency Server Push

    作者:Ilya Grigorik

    翻译:孙绍轩

    服务器推送(Server Push)是高效的、延迟低的数据交换方式。如果数据发送端与接收端都在互联网中公开可见,可以使用PubSubHubbubsimpler Webhook等方法完成任务。但是如果数据接收方在防火墙内、在内网或它只是一个浏览器(只可以向外发送数据请求,无法处理传入的数据),则实现服务器推送就更难了。如果你有冒险精神,你可以建立一个反向HTTP服务器。如果你寻求可靠的解决方案,也许你要等待HTML5的WebSocket’s API特性了。但如果你需要即刻可以实现的解决方案,你可以妥协一下,使用异步推送模式来代替,你可以使用Comet,也被称为反向Ajax、HTTP服务器推送或HTTP流。

    早在2006年Alex Russel提出了一个不坏的技术思路,那就是长连接(Comet)概念:从客户端发起并保持一个连接直到数据出现并传送(long polling),或者永远保持一个连接,通过它推送数据到客户端(streaming)。这两种方法的好处是数据传送非常及时。因此长连接技术广泛用于聊天应用(Facebook, Google, Meebo等)以及实现即时触发的机制。

    Nginx变成一个长连接服务器

    实现长连接服务比较大的问题是特殊的隐形需求以及事件驱动web服务器能否高效处理众多的长连接。Friendfeed的Tornado服务器是一个标准应用级服务器的好例子。另外,感谢Leo Ponomarev的努力,你现在可以用nginx_http_push_module插件使你的Nginx服务器变身成为一台完全功能的长连接服务器。

    使用自定义的一套框架结构,Leo的插件只提供两个对外的接口:一个是订阅者,一个是发布者。客户端连接Nginx服务器,创建针对一个频道的long-polling长连接并等待数据。同时,发布者只是简单的将数据使用POST方法提交给Nginx,插件收到数据后将它一个个发给等待的客户端。这表明发布者不需要直接传递数据,它只是一个简单的事件产生器!没有比这个更简单的方法了。

    还有更高的功能是,客户端和发布端可以建立任意的频道,并且插件也提供消息队列功能,这表明Nginx服务器会在客户端断线的情况下临时保存消息。队列消息可以按照时间、等待列表长度或内存限制大小来失效释放。

    NginxRuby配置例子

    一开始,你需要从源代码编译一个Nginx。解压源代码包,从GitHub获取插件的源码并放入Nginx的源码目录,然后使用下面的参数编译(./configure –add-module=/path/to/plugin && make && make install)。下一步,参考readme文件和协议文件,了解所有的参数选项。一个多客户端接收信息的配置例子如下:

    > nginx-push.conf

    # 内部发布点(保证私有或不对外公开)

    location /publish {

    set $push_channel_id $arg_id;      #/?id=239aff3 或类似的文本标示

    push_sender;

    push_store_messages on;            # 打开消息队列

    push_message_timeout 2h;           # 2小时后消息失效

    push_max_message_buffer_length 10; # 保存10条消息

    push_min_message_recipients 0;     # 清除前最小接收人数目

    }

    # 公开的长连接接收点

    location /activity {

    push_listener;

    # 一个频道编号能有多少客户端同时连接

    # – last: 只有最频繁请求的客户端能保持,其它连接返回409

    # – first: 只有最早连接的那个客户端可以保持,其它连接返回409

    # – broadcast: 任何数量的客户端连接都会是长连接

    push_listener_concurrency broadcast;

    set $push_channel_id $arg_id;

    default_type  text/plain;

    }

    当你编译配置好你的Nginx服务器,并且启动它,我们可以建立一个简单的广播场景,一个数据发送广播方,几个订阅信息接收方来测试我们的长连接服务器。

    > comet-push-consume.rb

    require ‘rubygems’

    require ‘em-http’

    def subscribe(opts)

    listener = EventMachine::HttpRequest.new(‘http://127.0.0.1/activity?id=’+ opts[:channel]).get :head => opts[:head]

    listener.callback {

    # 打印所获取的内容,并重新订阅这个频道

    # 使用last-modified头去忽略之前已经获取的数据。

    puts “Listener recieved: ” + listener.response + “\\n”

    modified = listener.response_header['LAST_MODIFIED']

    subscribe({:channel => opts[:channel], :head => {‘If-Modified-Since’ => modified}})

    }

    end

    EventMachine.run {

    channel = “pub”

    # 每5秒钟发布一个新的消息

    EM.add_periodic_timer(5) do

    time = Time.now

    publisher = EventMachine::HttpRequest.new(‘http://127.0.0.1/publish?id=’+channel).post :body => “Hello @ #{time}”

    publisher.callback {

    puts “Published message @ #{time}”

    puts “Response code: ” + publisher.response_header.status.to_s

    puts “Headers: ” + publisher.response_header.inspect

    puts “Body: \\n” + publisher.response

    puts “\\n”

    }

    end

    # 打开两个客户端

    subscribe(:channel => channel)

    subscribe(:channel => channel)

    }

    nginx-push.zip (完整的Nginx配置和Ruby代码)

    在上面的代码中,每5秒钟数据发布端向Nginx服务器发出新的事件,服务器将数据通过长连接转发给两个订阅的客户端。当消息发送到客户端,服务器会断开他们的连接,客户端会立即重连并等待下一次数据的到来。结果就是使用Nginx实现了一个数据发布端到客户端的实时消息推送机制!

    期待生产环境下的长连接服务

    Leo的模块还在开发期,还需要时间来稳定下来,但它是一个需要关注的项目。最近的更新计划都着重于bug修复,未来的计划里有描述要加入流的模式:代替现在每次数据获取后都要重连的情况(long polling),Nginx会保持连接,将数据一段段的实时传送给客户端。拥有这个功能后你能很方便的部署你自己的信息触发式API(例如:Twitter流)。

    最后,不要忘记数字不断增长的其它Nginx模块,或者如果你感兴趣的话,可以参考Evan Miller编写的指引来开发自己的Nginx模块。

    Tags: ,

  • 26 十 2009 /  互联网技术

    Software Developer 2.0 2009会议上以及之前参加的一些会议上看到一个现象,大厂商都开始敏捷了,如果你现在还徘徊是否要敏捷,我觉得可能为时已晚,你要立刻敏捷起来!

    SD2.0 2009上微软给大家介绍了Visual Studio 2010,从界面上来看沿袭了Office 2007的风格,工具条排列很花哨,也有一大堆微软经典的wizards,利用这些向导可以很方便的完成开发工作。一个被我关注的重点是VS2010整合了开发流程中除了编码以外的东西,比如版本控制、缺陷管理、UML建模等都融合进入这个集成开发环境,并且它还拥有敏捷开发的一些特性模板,单元测试模板用于测试驱动开发。不难看出微软为了方便开发者,将最近开发管理所需的功能都列入到它的VS2010里面去了,而且是全网络化的解决方案,开发人员之间是可以很方面的共享信息的。相信在微软内部也有团队在实施敏捷。

    IBM的一场演讲中也透露出,IBM内部软件开发也在实施敏捷,而讲演者Robert Degg来自Rational,他主要的工作就是在IBM内部帮助各个软件开发部门实施敏捷。

    通过网上的一些文档介绍,Google, Yahoo!, Facebook, Twitter, eBay等大型互联网公司都在实施敏捷开发并有些成效。敏捷已经不是两三年前大家都在观望的局面了,已经不是只有创业团队敢于尝试的一种开发方法了,渐渐的你会发现身边的软件公司都多少的运用敏捷开发的方法,你还犹豫什么?

    忽悠大家半天再来说说如何实施敏捷

    也许敏捷方法并不和你现在使用的方法有太大的差异,我认为我们要从小事出发,用敏捷方法解决我们现在特定的问题,这样才能积累所有人的信心继续朝着更高的方向改进。毕竟老板只会看效果,如果不能在短时间内达到效果,说到天花乱坠也没有用。下面列举一些可以注意的小点,你可以按照你具体的情况来选择实施。

    • 对待需求按照重要程度排序,一段时间内只完成确认的最终要的任务

    其实很多开发团队也是这么做的,只是敏捷方法提出频繁迭代的概念,让完成需求有一个特定的周期,并且这个周期要尽可能频繁的迭代。每个周期完成的是完整的事情,没有完成的百分之多少的概念,只有完成和没有完成。这样保证每个迭代有工作的产物,保证下一个迭代万一出现问题我也能拿出上一个迭代的成功产物。

    另外重要程度排序也会使得最重要的业务需求最先完成,不至于做的半天都是无用功。

    迭代周期中不加入其它新的变化导致在一段时间内足够的清净让开发人员来完成工作。

    • 测试驱动

    也许这个题目太大,你可以缩小化成自动单元测试,因为要自动测试所以你要写测试脚本,也许你会在写完程序后懒得写测试脚本所以把测试脚本编写在程序开发前面。选择一个适合的测试框架,你会很快达到这个目标。你会发现不必为了找一个bug花费很多的时间,如果你要查问题,就给自己一个假设,用这个假设实现一个测试来验证吧,逐渐的你的测试脚本会限制你,一有bug测试就无法通过了,你就不需要找而是直接修复发现bug。

    对于小团队,这里其实更重要的是让单元测试从无到有。

    • 配对编程

    也许你会对这个很怀疑,但我能说的是,这只是一个形式,如果你仔细观察,在你公司内部,也会经常因为某一个人解决不了一个问题而抓住另外一个人,两个人一弄就是一下午,也许问题已经解决了,两个人也会继续一段时间。配对本来就是一个很自然的事情。

    配对根本解决什么呢?

    1、人的经验问题,不可能都是全才,配对有利于带新人,或者让两个不同领域的开发人员能互相熟悉或产生升华。这点通常在配对前两个人一起设计而体现。

    2、代码复查;首先我相信大部分开发团队是没有这个独立的工作内容的,但它真的很重要,代码复查可以让所有人在一个编码标准下开发,复查可以让一些有问题的设计思路更早被发现,因为一个不好的设计并不会产生bug,但也许它影响了后续的性能或者灵活的可扩展性。因此如何引入代码复查而又不增加而外的开发负担呢?配对编程是个很好的方法。

    3、形成通才而不是很多专才;通常我们担心某些点没了某些人就不转了这种情况,一个是不利于公司管理,二来也不利于那个人发展(我因为精通某一个方面就弄要负责那个方面,也许我都已经厌倦了,但无法自拔,解脱只有辞职换工作了),配对编程的经验共享使得可以弱化上述问题,并且所有人被灌输的是你感兴趣的部分你都可以了解,不是对每个开发人员发展都有激励作用嘛?

    • 任务管理或缺陷管理

    也许这不算敏捷里面的东西,但它和敏捷开发密不可分,例如Scrum里面的burndown chart就是代表bug被解决的趋势。老外讲究的一个思路是:你如果想优化一个事情,就首先要弄清楚如何度量这个事情,只有度量的结果才能反馈你的改进是否有效。因此无处不在的数据会很直接的体现项目的状况。

    现成的有很多系统可以辅助你进行任务管理和缺陷管理,我推荐Trac,一个使用Python编写的集成系统,用于开发中知识共享,围绕它也可以找到很多第三方的插件来满足你的需求。

    ok,对比一下你的现状,也许你离敏捷并不遥远,只需要参考一下将好的东西吸取到你现在的过程中,就这么简单,开始行动吧,也许未来你也能创造出一个什么敏捷方法!

    Tags:

  • 26 十 2009 /  互联网技术

    上个星期参加为期三天的Software Developer 2.0 2009大会,我了解到各个手机系统平台提供商的现状,现归纳总结一下。

    Android

    Google推出的东西总是可以在那个领域溅起巨浪,Android以免费开放的原则推出,引起了众多人的关注,发布了两年后这个东西逐渐成熟起来,支持的手机也越来越多了。总体都往好的方面发展,中国地区的开发者可能更加关注,希望这个年轻的项目可以尽快开花结果。

    SymbianOS

    老牌智能手机操作系统大哥,被Nokia收购了以后沉默了一小段时间,变身成Symbian Foundation出现在我们面前,给大家的惊喜是,免费、开放,果真是被Google挤兑的不行了。计划明年2010年全部开放所有的系统代码和授权,个人估计山寨机又会更火,因为又有一个好用的系统平台可以选择了。BTW:Nokia最近出的手机真是没有什么新意,gphone和iphone两面夹击,够它受的了,祈祷吧。

    iPhone下的Coco touch

    苹果是相对封闭的,我们只能去写iphone或者ipod touch上面的应用,平台就看着眼馋吧,个人觉得这种封闭的、控制力很强的软硬结合物才能做出精品。

    Windows Mobile 6.5

    如果你是微软的崇拜者,你可以继续关注,不过总觉得PC上的一个概念移植到手机而不用手机的思路来设计一个系统的话,不会太好用。不过这个开发会是很简单,强大的Visual Studio永远是开发利器。这次开会也有幸看到Visual Studio 2010,大厂也开始敏捷了,呵呵。

    WebOS

    Palm借助WebOS推出Palm Pre新一代手机系统,一个巨人倒下了,如果能再次站起来的话,那会是非常强大。希望能看到这一天,因为Palm是最能体会移动设备操作的厂商,现在其它平台下很多操作都有palm的影子。期待它再次回到主力。

    BlackBerry

    封闭的软硬系统以及特定的应用场景,如果不是针对商业应用开发的开发者就不用太关注它了。

    总结

    平台还是很多的嘛,作为开发者的你也不能三心二意,专注在一个平台上先做大是我的忠告。至于选择哪个平台,那就要看自己的情况了。Android借助中国移动Ophone的力量蓄势待发,强烈的建议重点关注。iPhone如果你是做国外业务也可以关注,如果是关注国内市场就可以稍微晚一点再说,因为从联通对iphone的定价,我十分怀疑它有足够的运营能力能将这个优秀的平台在国内搞好(苹果也不是吃素的,一向会很强硬)。Symbian有足够的有开发经验的开发人员,想做应用找现成的人就好了,无需再自己研究,所以这个平台关注就好,只要你的应用有竞争力,补充上Symbian平台可以说是小菜一碟。

    让暴风雨来得更猛烈些吧,只有平台竞争更激烈,运营商竞争更激烈,才会有更多的好处落在用户和开发者身上,我们期待这一天早一些来临吧!

    Tags: , ,

  • 10 十 2009 /  互联网技术

    写在前面:

    总觉得学习英语要实践点什么,计划作为毕业印证我要翻译一本技术书籍。现在我还没有毕业,所以接下来的日子里,尝试翻译一些短文,热热身先。

    ———————华丽的分割线———————————-

    Python内建异常清单

    by Al Lukaszewski for About.com

    翻译:Yorgo Sun

    原文:http://python.about.com/od/pythonstandardlibrary/a/lib_exceptions.htm

    下面是一个完整的Python运行时会抛出的错误列表。大部分错误都可以一目了然,我添加了一些注释来使得它们更加清晰。这参考并扩展了Python 2.5文档中“内建异常”的章节。

    • BaseException: 所有内建异常的基础类。
    • Exception: 所有的内建的、非系统预置的异常均继承这个类,所有用户定义的异常也应该继承这个类。
    • StandardError: 所有内建异常的基础类,除了StopIteration,GeneratorExitKeyboardInterruptSystemExit StandardError 是继承Exception而来的。
    • ArithmeticError: 一些内建算术错误异常的基类,如: OverflowErrorZeroDivisionError,FloatingPointError.
    • LookupError: 当一个键值或索引在数组或序列中无效时所触发的所有异常的基类: IndexError,KeyError. 它也会由sys.setdefaultencoding()直接触发。
    • EnvironmentError: 所有能发生在Python系统之外的异常的基类:IOErrorOSError.
    • AssertionError: 当判定条件失败时,触发此异常。
    • AttributeError: 当一个属性被引用或赋值时出现错误会引发此异常(当一个对象不支持属性被引用或赋值时,会触发TypeError异常)
    • EOFError: 当内建函数(input() 或 raw_input())达到文件尾时触发此异常。(注意:文件对象的read() 和 readline()方法处理方法不同,当遇到到达文件尾部的情况时会返回空字符串)
    • FloatingPointError: 浮点操作失败时触发此异常。
    • GeneratorExit: 当调用生成器的close() 方法时,触发此异常。它直接继承了Exception 用于替代 StandardError ,毕竟这是一个技术手段并不是一个错误异常。 2.5版本新加特性。
    • IOError: 当I/O操作(如一个 print 语句、内建 open()函数或调用文件对象的某个方法)因为I/O相关的问题而失败时触发此异常,例如:“无此文件”或“没有足够的磁盘空间”。这个类继承于EnvironmentError
    • ImportError: 当 import 语句无法找到对应的模块定义或 from…import 无法找到对应名字的内容时触发此异常。
    • IndexError: 当一个序列子集超出范围时触发此异常。(索引会被截取以保证在合理的范围内; 如果索引x不是一个整数, TypeError 异常会被触发)
    • KeyError: 当键值并不存在于图(字典)中,会触发此异常。
    • KeyboardInterrupt: 当用户按下终止键时触发此异常(通常是Ctrl+C或者Delete键)。
    • MemoryError: 当某些操作导致内存耗尽但应能恢复的情况下(通过删除一些对象来释放内存),触发此异常。
    • NameError: 当无法找到对应名字的本地变量或全局变量时,触发此异常。这只针对无效的名字。 附带参数是包含了无法找到的名字的错误信息。
    • NotImplementedError: 这个异常继承于 RuntimeError. 用户定义基类后,抽象方法可以触发这个异常来要求派生类必须实现该抽象方法。
    • OSError: 这个类继承于 EnvironmentError ,主要用于os模块的os.error异常。
    • OverflowError: 当一个算术运算太大导致数值溢出时触发此异常。
    • ReferenceError: weakref.proxy()函数产生一个弱引用代理时,此异常被触发。弱引用代理通常访问一个被引用对象的属性,但这个对象已经被垃圾回收。更多的弱引用信息,请参考weakref模块。
    • RuntimeError: 当一个无法分类的错误发生时,触发该异常。
    • StopIteration: 当一个迭代器的 next() 方法无法获得更多的值时,触发该异常。
    • SyntaxError: 当语法解析器遇到语法错误时触发此异常。
    • SystemError: 当解释程序遇到一个内部错误,但是情况看来可以纠正,不需要放弃退出。辅助参数是一个字符串,标明在更顶层什么出错了。
    • SystemExit: 这个异常被 sys.exit() 函数触发。当这个异常没有被有效处理,Python终止程序并退出;没有堆栈信息打印。如果辅助参数是整数,它表示系统退出状态(和C语言的exit()函数类似);如果它是空则退出状态为0;如果它是其它类型(例如字符串),这个对象会被打印输出,并且退出状态为1。
    • TypeError: 当一个操作或函数调用一个不恰当的对象类型时,触发此异常。附带参数是一个字符串,表明具体的不匹配的类型。
    • UnboundLocalError: 当在一个函数或方法内引用本地变量但变量并没有赋值时,触发此异常。
    • UnicodeDecodeError: 当一个Unicode相关的编码、解码错误发生时,触发此异常。它是ValueError的子类。
    • UnicodeEncodeError: 在文字编码时发生一个Unicode相关的错误则触发此异常。它是UnicodeError的子类。
    • UnicodeError: 在文字解码时发生一个Unicode相关的错误则触发此异常。它是UnicodeError的子类。
    • UnicodeTranslateError: 在转换文字编码时,当一个Unicode相关的错误发生,触发此异常。它是UnicodeError的子类。
    • ValueError: 当一个内建操作或函数接收了参数,参数的类型是对的但值并不符合并且无法匹配一个更加精准的异常(例如:IndexError),触发此异常。
    • WindowsError: 当Windows系统下特定的错误发生或当错误编号无法映射 errno值时,触发此异常。
    • ZeroDivisionError: 当除法或取余操作分母为0时,触发此异常。附带的参数是一个文字信息,标明了运算类型和具体运算数据。

    Tags: ,