随笔-50  评论-528  文章-5  trackbacks-4
  2008年6月6日
     摘要:
测试网址http://www.yluck.com/
其实我很想用silverlight+asp.net(C#)做一个,但是不太了解silverlight是否有flash那样的“一次性多选控件”。
欢迎讨论silverlight+asp.net(C#)的可行性

  阅读全文
posted @ 2008-06-06 16:56 Kai.Ma 阅读(1955) | 评论 (14)编辑

    大家从各个开发语言的优缺点和适用领域,一直讨论到设计模式、框架、重构、单元测试,乃至敏捷编程,最后都讨论到了软件开发过程管理,甚至都谈到了盈利模式和中国软件的悲哀。

    最后不了了之,都觉得改善中国内地现在的软件生产状况不可能。

    为什么呢?

    我重新把这几天大家的讨论留言翻了一遍,发现大家的软件团队都存在着这样一种普遍现象

    1、大部分人所在的公司,开发人员仅3-5人,多的在10人。别看就这几条枪,还从售前支持,软件开发,测试、打包发布、文档编写、实施安装、培训、技术支持都做。
    这还不算什么,而且几乎是一个人负责一个产品或一个项目,一个人从头跟到尾,而且负责多个客户的维护工作。
    这还不算什么,而且随时老板会找来八竿子打不着的新活,要的还挺紧,突然要开发,打乱了所有的计划,最后都懒的按计划行事,每天撞钟,老板有事就吩咐,没事就上网,还不让听歌,当然更不让打游戏。甚至还不让看技术书籍,呵斥不干工作。只能上网装作在工作。

    2、老板和员工互相斗智斗勇,在年终奖、报销、出差、平时福利上啊,都明争暗斗。老板卡的紧,员工就在项目和产品上下药,还不知道是谁占了谁便宜,谁给谁打了工。

    3、员工一边在刻苦钻研各种开发工具,阅读源代码,学习做DEMO例子,阅读UML、设计模式、单元测试、敏捷编程等等,一边却懒的修改现在公司的产品,有问题就打补丁,客户不嚷嚷就懒的修改,代码不优化,界面不友好,架构没架构,代码不封装

    但是,在讨论中,我时时都强烈感觉到,大家是想把产品开发好,把开发过程管理的井井有条,但是都心有余而力不足。阅读了N多软件工程的书籍,从重型方法到轻型方法都阅读了,但都无法把现在的开发状态一点点扭转好。

    许多人想闹革命,把现在这些产品和团队都砸塌,然后重新来过,但这只是梦想,说说而已。只能希冀下一次跳槽,能找到一个好的公司,把自己平生所学全部发挥出来,但这好像也只是梦想,因为交流了一下,大家彼此的境况基本相同。

    一些极端主义者自己开了公司,才发现不持家不知道油盐贵,现在自己和手下变成了老板和员工的关系,走了过去的老路。

    更有一些极端主义者辞职,自己做软件,最后由于生活拮据或做做发现这个软件没什么意义,就丢弃了自己的梦想,随便找一家公司开始沉默撞钟。

    一些聪明的家伙,有的入了外企,有的进了大的网游公司,有的进了外包公司,有的进了大网站公司,都是讲究大规模开发的公司,希望能找到一条中国式团队开发产品保证之路


    作为小软件公司,我们真的无能为力了么?我们真的成为炮灰了么?

    但是,中国软件行业大部分都是这样的公司。从每年的CSDN、51aspx的程序员调查都可以看到,中国软件公司大部分都保持在这种开发团队规模,开发人员大部分都在毕业1-3年。

    我们是在等待时间让人变得成熟么?我们是在等待时间让人变得技术综合实力增强么?

    依笔者看,作为中国软件群体最大的小软件公司,需要的不是UML/RUP/CMM这些重型方法,不是前几年大家关注的小组开发方法,也不是敏捷编程这样的结对方法,我们都无法有这样的资源实现这样的方法。

    但是,想想,星星之火可以燎原。红军能从爬雪山过草地起家,最后解放全中国。我们就没有方法?

    那我们就需要想,就我们目前能拥有的权力和资源,我们如何一点点改进。我们需要的是从游击队到兄弟连,从兄弟连到正规军的方法。我们现在还处于游击队,一个队长领了一帮游兵散勇,有的人甚至没有枪还背着大刀,有的人还没杀过鬼子。

    首先,要把我们自己变成兄弟连。

    我常常观看国际著名的CS战队的比赛录像,他们配合的多好啊。如果他们都单兵作战,那么早就死翘翘了。这和咱们的软件开发多么相像。我们多么神往这种默契的配合,打的多么流畅。我们要的就是这个。他们也不几个人么。

    那让我们来分析分析吧。

    我们想好好专职的开发软件,但我们的时间都被实施安装、培训、技术支持占去了。为什么我们要做这些?是因为我们软件没有操作说明,其他部门人都不会用。而且我们也没有培训机制,其他部门人更不会用。而且我们的软件不稳定,其他部门人都拒绝实施。由于我们软件不稳定,老出问题,出了问题其他部门人也帮不上忙,只能我们自己去做技术支持。

    从以上来看,主要矛盾就是在:操作说明、培训机制、稳定性。如何保证这三点。而且从以上来分析,稳定性是最重要的。不稳定,你即使有操作说明和培训机制,其他部门人都躲着实施,谁想去客户那里尴尬丢脸挨骂呀。所以,其他部门人会找各种理由向老板告开发部的状,以躲避实施,说软件太烂,根本无法拿出去。这也就是开发部往往和其他部门关系都不好,开发人员老抱怨自己就闷头辛苦开发解决问题,没有人说好,却被奸人陷害。天长日久,积怨颇深。其实说起来,根源还在开发部自己这里。

    如何保证稳定性?

    大家第一想到的就是招测试人员。当然,一些公司的老板是拒绝养测试人员的。另外,如果你只想到招测试人员,其他方法不配合测试人员,即使有了测试人员,软件稳定性仍然不会有提高。所以,有一些工作,是不管有没有测试人员,都必须是我们开发人员要做的:

    每个人的技术水平都参次不齐的,每个人对自己代码的负责认真性也都是不一样的,所以要想提高稳定性,必须专门从队伍中找一个人,他作为公共代码开发员。每个产品或项目的修改需求,必须首先经过他的思考,能做成公共代码,能封装成函数,就他来做。其他的程序员只管调用函数,实现客户UI操作和辅助功能。这个公共代码开发员必须具备以下能力:
    A、参与过几个主要项目的开发、实施、支持。这样,他对客户需求有综合的把握。如果队伍中没有这样的人,只有开发经理一个人有这样的经理,那么接到客户需求,分析客户需求,分解析辨是公共代码员来做还是其他开发人员来做。
    B、公共代码开发员具有负责认真的工作态度,代码细心严谨考虑周详异常保护做的到位内存创建释放有头有尾,代码优美,代码可阅读,代码重构,代码性能和稳定都高
    C、公共代码开发人员的技术能力高,知道封装成什么样的函数接口,在灵活性,以后的修改变化性上最好

    应该说,找一个技术能力好的,工作认真负责的人,应该是不难找到的。而且专门做这件事,不让他参与各种杂事,他是应该能干好这件事的,而且会越做越好,这就是术有专攻。

    刚才还讲到一件事,那就是开发经理要熟悉客户需求,而且是深刻理解客户需求。

    客户需求,客户需求。这个让开发部最头疼的字眼。每当想起客户需求,就想起了以下这些话:
    1、程序员说:这是你们家个性的需求,太邪门,我们不做。客户说:不做我们找你们老板去,我们是花钱买了你们的产品的。
    2、客户说:我不会用鼠标,你给我做一个语音输入吧。我们还想要一个类似QQ的东西供我们内部沟通,你们给我们做一个吧。程序员:我晕。
    3、程序员说:等你们内部斗争完,你们协调完了,我再调研需求。

    似乎,我们在需求上无能为力,我们永远在追赶客户的需求,满足他们的现状,把N多家的客户需求都加进软件中,只要能实现的,我们尽量咬牙实现了。

    最后,我们发现,我们的软件无比复杂,谁也不会用了,连开发部门都不会用了,谁也不知道这个需求当时为什么是这样的。因为无比复杂,所以实施、培训、技术支持都成了问题,稳定性更成了问题。代码互相交叉,根本无法理清有多少交叉影响点。维护的程序员都快崩溃了,天天在祈求,千万别接到客户电话,千万别接到客户电话。

    这个问题终归是问题,而且是软件开发最大的问题。虽然我们也动用了这样的技巧:
    1、客户业务部门不能随便提需求。必须集中汇总到客户IT部门,由客户IT部门汇总过滤完,再集中报给软件公司
    2、客户IT部门的需求,必须客户方负责IT项目的老板签字才能生效,才能报给软件公司
    3、不能随时报,每3个月集中报一次
    4、不能口头报(即使在现场实施支持也不行),不能电话报,只能MAIL或传真来报
    5、必须按我们规定的格式报,要严格写清楚需要实现的功能的界面,输入数据或输出数据,输入输出数据的格式要求,谁操作,多长时间操作一次。
    6、软件上线后只能免费修改3次。以后再有需求,就必须另签合同另收费,否则不予修改。

    经过这么几招,客户也疲了。需求是不提了,开发部欢呼雀跃。但我们真的做好了么?难道客户真的满意了么?客户为什么要用我们的软件?难道仅仅是为了把他们现在手工做的,然后转到计算机去做。让计算机的查询统计计算速度代替人工?

    客户为什么要提这样的需求?客户要根本解决什么问题?这些问题谁来想,谁来想解决办法?

    OH,My God!我们无能为力,因为我们是技术人员,我们不懂业务。

    那这个问题谁来解决?

    程序员苦笑了:没有人解决,也没有人能解决。客户就要,你不做他就要给老板打电话。

    噢,那就让程序员的噩梦继续吧。谁也救不了你,能救你的只有你自己。

    要救我们自己,必须我们自己走出我们自己。谁让我们就处在这样的处境呢?我们都想过的好,只能我们自己救我们自己。

    那我们就鼓足勇气,走出来,从我们的设计模式、OO、软件工程、虚拟接口、反射、持久化、框架中走出来。开发经理来承担起客户行业研究来:
    1、客户行业这个群体有多大?大中小规模各有多少家,各分布在什么省?我们面对的最佳客户是什么规模什么信息化程度的?我们的次佳客户是什么规模什么信息化程度的?
    2、我们的上层竞争对手、本层的竞争对手、下层竞争对手目前的产品怎么样?他们各自的优点是什么?他们各自的缺点是什么?我们应该突出的优点是什么?我们的缺点是什么?
    3、客户行业的过去5年,现在2年,未来3年的发展历史和趋势是什么?他们面临哪些挑战和机遇?
    4、我们现在所做的典型客户,他们的组织结构,人员规模,每个岗位每日业务流程、每个岗位每日每周每月每季每年的异常处理业务流程,每个岗位每日每周每月季每年的输入表格,每个岗位每日每周每月季每年的常用数据查询,每个岗位每日每周每月季每年的统计报表
    5、针对以上的了解,客户面对未来挑战和机遇,未来应该如何变更他们的岗位和职责和流程,尽量流程少,效率高,运转快?

    其实,开发经理就相当于业务架构师(因为我们还是游击队,不可能有专职的业务架构师),公共代码开发员就相当于技术架构师。

    柳传志说的非常好:搭班子,定战略,带队伍。你班子不行,上什么需求管理软件、版本管理软件、项目进度管理软件、自动测试、自动集成软件,都是无法落地执行的。

    有了夯实的业务+技术,功能实用、功能符合客户操作、功能稳定。这是软件最基本的要求,就都能满足了。这时候再招测试人员,就能把质量再夯实了。

    而且,测试人员由于熟知产品,他们还能做技术支持呢,这样可以有更多的开发人员来专职开发,开发的专业性就能越来越提高了。

    好的产品,还需要有好的文档和培训,否则其他部门还是不会接开发部的产品的。

    那就招一个文案人员,写帮助说明,制作操作视频,制作学习版数据库,参与辅助测试(这个很重要,否则文案人员不熟知产品,无法写出有质量的文案)。有了这些文案的基础,最熟悉产品的非开发人员就有了两个岗位:测试兼技术支持,那么文案就兼起培训工作(由于他自己写文案自己用自己的文案做培训,在培训中会有各种提问,会更加增进他对文案和产品的理解,能写出更好的文案。而且他不是开发人员,他能站在使用者的角度上来写来讲,而且他属于开发部门,他会给产品开发带来更多更好的产品易用性建议)。

    好了,开发部的四套马车终于起来了,这就是我要讲的开发模式:从游击队转变为兄弟连,从软件作坊走向

    记住:业务架构、技术架构、测试兼技术支持、文案兼培训,四套马车。

    我们一直用它,效果很好,搭建团队容易,循序渐进不革命。

    有了这么好的团队,就能比过去产出更好的软件,软件的质量,软件的进度,软件的竞争力就都上来了,再上各种管理软件:如项目管理软件、版本管理软件、BUG管理软件、自动测试软件,就水到渠成了。

    其他部门也愿意接软件了,软件的实施和培训和技术支持都被其他部门接过去了。开发部门也终于专职专业起来了,整个公司都很协调了,部门间也不互相陷害抱怨了。公司发展速度蹭蹭的。

    老板看着形式这么好,也不抠门了。奖金福利随之而来。老板看着公司产品销售这么好,也不用再为公司生存发愁了,不用随处找单子养活了,给开发部门更带来了专业理顺的计划发展。老板也开始重视研发部门了,研发部门在公司的地位高多了,给与研发部门的资源和支持也更多了。

OH,My God!

posted @ 2008-06-06 10:20 Kai.Ma 阅读(28) | 评论 (0)编辑
  2008年5月28日

将内网的程序上传至外网后,出现“检索 COM 类工厂中 CLSID 为 {E5FF9F62-0E7C-4372-8AD5-DA7D2418070C} 的组件时失败,原因是出现以下错误: 80070005”。

外网服务器也安装过Jmail,但根据报错,明显是组件没有被正确注册。

利用Jmail的安装包,卸载、重新安装也不行,最后采用极端手段。
将jmail.dll拷贝到服务器的system32目录下 ,开始-运行-CMD-输入regsvr32   jmail.dll
才算搞定。

posted @ 2008-05-28 13:58 Kai.Ma 阅读(63) | 评论 (0)编辑
  2008年5月27日
  • 职位: 网站程序员
  • 薪金: 4000~6000
  • 有效期至: 2008-06-06
  • 工作地点: 朝阳区 地铁5号 北苑北站 附近
  • 公司名称: www.YLuck.com
  • 简历投送邮箱: kai.ma@163.com

  • 学历: 大专
  • 是否应届: 非应届
  • 年龄要求: 25~27
  • 性别要求: 不限 

    我们组建了一个非常优秀的团队,经过4個月奋斗,创立一个非常有前景网站,已经开始融资,反响非常好。
    因为项目需要,非常期待有asp.net网站程序员加入。
    要求有下面几点。

    • 至少2年asp.net(C#)网站开发经验。经验很重要
    • 熟悉jQuery脚本库下的javascript客户端编程。网站离不开脚本,jquery库很不错。
    • 必须有过团队合作经验,这点最重要。因为我们的项目不是一个人的项目,希望你能配合。
    • 情商好,沟通能力强,比较服从安排。大部分时候能按规范做事,当然我们会给你自由发挥的空间。


    作为你辛苦工作的回报,在我们一起相处的日子里,团队会尽力满足你个人物质和精神上充足、学习、表现自我、结识行业内新朋友等需要。

    如果有兴趣,请发简历联系我。我会及时给你回复。
    Email:kai.ma(at)163.com
    QQ:29121937
  • posted @ 2008-05-27 22:16 Kai.Ma 阅读(697) | 评论 (23)编辑
      2008年5月14日

    网上流行的多文件上传,都是上传之后,用日期时间命名。都认为方便、简单,似乎还能避免同目录下产生相同的文件。
    代码大多如下:

    string 新文件名 = DateTime.Now.ToString("yyMMddHHmmss");

    上面这行代码会导致很有趣的bug:那就是当网站繁忙很多人同时上传的时候,或者一个人多文件同时上传的时候,你会发现,你传上去文件,经常性(跟别人)都是一样的,经常性“丢掉”一些图片。

    你会奇怪,为什么?

    很简单,服务器处理太快了,几乎1秒内就处理你的多文件上传请求,这一秒内,所有的文件名都相同(因为上面那个行代码就只精确到秒)。

    OK,既然是文件名相同,我精确到毫秒,不就解决了?于是有了下面的代码:
    string 新文件名 = DateTime.Now.ToString("yyMMddHHmmssfff");//精确到毫秒,防止1秒内被处理的文件获得的新名称都相同
    经过上面的改造,会发现问题减少了很多,不再经常“丢”图片了……但是,偶尔还是有照片丢失的情况发生……

    知道原因吗?MSDN告诉我们:“Windows系统时钟精确到10~15毫秒”,也即说,DateTime类型只能精确到10~15毫秒。如果用时间命名,即便精确到毫秒,10~15毫秒内处理的文件,名字仍然会相同,有趣的bug仍然会产生。

    故,不推荐使用日期时间命名文件。

    那怎么办呢?用Guid!唯一的、一出生即与众不同的家伙,它的唯一性,理论上保证了同一目录下无可能出现重复的文件名。
    string 新文件名 = Guid.NewGuid().ToString("N");

    posted @ 2008-05-14 10:20 Kai.Ma 阅读(867) | 评论 (21)编辑
      2008年5月10日
    我有几百美元,paypal楞是给我扣了两年……就是不给结。原因据内行用户说是在同一机器上使用了2个帐号转账。

    又要身份证,又要我交水电气费单,又要住址证明,还要讲清楚交易来历。后来我冒着隐私透露问题,愣是通过【截图】取证,把关键证据给补上了,他们还是不办,一定要交水电气费单。

    有点气愤,我都在【截图】取证中解释了,自己住公司房子,不用交水电气费,也就拿不出水电气费单。只要是一个明白道理的人,一看我的截图,就知道整件事情的来由,绝对合法,合理。

    可paypal中国区工作人员就是不办,而且用自动回复处理……

    前前后后2年,快把我耐心耗没了,想想也就几百$,在这上面花的时间,够我挣N个几百$。

    我怀疑那的工作人员(Paypal中国国内的)都是机械人,不会看文件,只会按程序办事。

    建议大家谨慎使用paypal,一旦出现问题,真的很麻烦。

    而且使用的时候,他们不会提醒你有哪些失误,让你去踩地雷,然后就扣你的款,扣到你失去耐心放弃这笔款。

    我想世界之大,有同样的朋友碰到类似的事情吧?

    谨慎使用类似的公司的服务。
    posted @ 2008-05-10 17:09 Kai.Ma 阅读(158) | 评论 (5)编辑
      2008年5月6日
      set   statistics   profile   on  
      set   statistics   io   on  
      set   statistics   time   on  
      go  
      你执行的语句  
      go  
      set   statistics   profile   off  
      set   statistics   io   off  
      set   statistics   time   off  
       
      执行完点消息!
    posted @ 2008-05-06 11:39 Kai.Ma 阅读(66) | 评论 (0)编辑
    软件不大,据说特方便,还有U盘版。参见园子里兄弟发的文章:推荐:偷懒利器 EmEditor 
    出行、即使去客户那边现场排除问题,再也不用背沉重的笔记本电脑了。
    希望这个东东能给我今后的代码编辑生活带来惊喜。
    posted @ 2008-05-06 10:31 Kai.Ma 阅读(93) | 评论 (0)编辑
      2008年4月24日

    【表A】与【表B】之间有外键约束(具体怎么约束的无所谓,因为外键和事务死锁没有绝对关系)。【表A】=主键表,【表B】=外键表。
    公司有几位程序员写的代码总是出现死锁,现在将事务死锁情况重现.

    using(事务)
    {
        
    try{
            
    for()//一个循环
            {
                
    if(查询【表A】有该【记录】==false)//这个查询没有用当前事务的数据库连接,而是新开一个数据库连接查询数据库
                {
                    将【记录】插入【表A】;
                    插入【表B】;
                }
            }
            事务.提交();
        }
    catch{
            事务.回滚();
        }
    }

     

    4月25日早9:00补充:以上代码逻辑如果放在一个存储过程里面,是没有问题的。但是放在C#中,程序员稍不注意,就很可能出现问题。出现问题的关键地方在“查询【表A】”。C#中,如果查询【表A】和当前的事务不是同一个数据库连接,而是新开一个连接,就会死锁(可以看留言中我的回复)。所以:要么
    1,查询【表A】改为使用当前事务的数据库连接(推荐用这种方法)
    2,要么按下面的进行代码改造,将事务移到循环体内。
    当循环只有1次的时候,上面代码运行没有问题。
    一旦循环大于1次的时候,死锁立即出现,运行SQL Server 2005的sp_who_lock,发现死锁的地方正是“查询【表A】”这块。为什么呢?
    因为:第1次循环,插入【表A】后,事务将【表A】设置了独占锁,但是第1次循环完后,事务并没有提交,也就没有解开【表A】上的独占锁。因为表A被独占锁了,所以第2次循环时,“查询【表A】”这个操作进行不下去(后面的插入【表A】更是如此),一直在等待事务提交以解开锁,但是事务运行到第2次循环的查询【表A】就死了,循环无法继续进行,也就不能运行到循环外边的事务.提交(),【表A】的独占锁永远没法解开死锁就这样产生了。

    既然知道了死锁的原因是因为循环里面没有解开独占锁,所以我们应该把事务.提交()放置在循环内。另外根据事务体的逻辑尽量少的原则,我们把事务的声明移植循环体内,使事务体的代码行数尽量少。代码如下。

     

    for()//一个循环
    {
        
    bool 有记录=查询【表A】有该【记录】;//将这个查询移出事务是良好的编码习惯,虽然这里不必要
        using(事务)
        {        
            
    try{
                
    if(有记录==false)
                {
                    将【记录】插入【表A】;
                    插入【表B】;
                }
                事务.提交();
            }
    catch{
                事务.回滚();
            }
        }
    }

    经过以上改造之后,几位程序员写的业务运行正常。

    由此总结:
    1,在C#等程序代码中使用事务,并在事务内进行查询的时候,特别要小心,确保该查询和事务使用的是同一个数据库连接。防止表被独占死锁。
    2,事务体内应尽可能少的逻辑,尽可能少的代码行数。
    3,4月25日9:00补充:防止事务死锁最好的方法,还是大家推荐的用存储过程,在存储过程里面使用事务(只不过门槛稍高,手工活儿稍多)

    posted @ 2008-04-24 14:24 Kai.Ma 阅读(1055) | 评论 (21)编辑
      2008年4月8日

    昨天同事做了一个网站局部功能发给我,他用的是Web site。我拷贝进VS2008的Web Application里面,发现编译总是不能通过。
    让他重新建一个Web Application,把Web site代码转移到Web Application后,发现
    可以编译了,直接拷贝的。

    以下是我回同事的信
    原因:
    我们采用的Web Application,不是Web site。因为你之前的版本缺少
    .designer.cs文件,这个文件是vs2008用来存放Webform服务器端控件的.CS(CodeBehind)定义的(.net 1.1时代就有的模式又回归了,不过换了个地方存放自动生成的代码),没有这个东西,自然不会认服务器端控件。

    Web Application的最大好处就是能将网站编译成一个dll,方便部署。大网站开发首选模式。推荐。

    posted @ 2008-04-08 11:34 Kai.Ma 阅读(133) | 评论 (2)编辑