解惑

解己之惑,解人之惑

分类:软件开发 (第2页共4页)

intersect的性能问题

我们有张表是存储用户自定义的类似tag的信息的,有一个功能是按照tag进行搜索,而且支持搜索多个tag查找同时使用这些tag的对象,最开始的实现就是使用的intersect,我感觉可能有问题,然后正好没有太多的事情,就试了下性能,发现那个SQL可以进行改造,变成group by 加 having的模式,一个查询搞定,弄了大概4万条数据,两个SQL(同时查4个Tag)的对比结果显示,前面的SQL会扫描整个表4次(和查询的tag的次数直接相关),并且有一次写入操作,而后面的只有一次扫描没有写入操作,时间上后面的SQL的性能是前者的两倍以上。所以对于同质的SQL的intersect可以转换为这样的group by加having的模式。

原来的SQL:

select ObjectID from ConfigObjectMetaData where KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 6769857814803370866 and ValueInt32 = 2 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 3984357063977881949 and ValueInt32 = 3 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160 and ObjectType = 10

修改后的:
select ObjectID from ConfigObjectMetaData where ObjectType = 10 and (
(KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705)
or
(KeyNameHash = 6769857814803370866 and ValueInt32 = 2)
or
(KeyNameHash = 3984357063977881949 and ValueInt32 = 3)
or
(KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160)
)
group by ObjectID
having count(ObjectID)=4

Windows下的文件定期备份

应该说这个是简单得不能再简单的事情了,但是在Windows下也不是很容易,主要是OS没有现成的工具,而自带的DOS命令又稍显弱了一点,稍微使用点技巧还是可以解决的。

既然是备份,当然备份到其它的物理机最好,所以第一步就是使用Windows的网络磁盘功能,把其它物理机的具有可写权限的目录映射到本地的磁盘,默认第一个应该是磁盘Z:

然后就是写一个批处理文件完成目录创建和文件拷贝,目录名是当前日期:

Z:
cd targetSubDir
set dirname=%date:~10,4%-%date:~4,2%-%date:~7,2%
mkdir %dirname%
cd %dirname%
copy originalDir\*.* .

简单的说一下,第二行就是进到子目录,如果你备份到本来就是映射盘的根目录,第二行就不用了。第三行是生成当前日期,%DATE%本来就是当前日期,但是格式里面包含空格和/,因此不是合法的目录名,我们把它转换为YYYY-MM-DD这样的合法目录名格式,需要说明的是,网上有文章说不同的OS的默认日期格式不一样,语言不同应该也不一样,我试的是2003Server版,英文。然后创建这个目录,进入这个目录,然后从本地的目录拷贝内容,如果需要备份的内容还包含目录结构,就把copy换成xcopy,originalDir就是本地的需要备份的内容的路径,最好是完整路径,例如c:\db。

第三步就是建一个Schedule Task,是每天跑还是每周或者每月就看自己的需求了,这个很简单,不多说。

超短的Iteration

项目正式启动,但是时间很紧,两个月时间要把对旧系统的修改做好,因为要赶他们的一个发布计划。两个月被划分成3个Iteration,扣除前期的讨论时间和预留的时间,实际就剩6周,所以一个Iteration就是两周,上周计划开始的时候还在讨论设计,不过这个也怪我,因为在Iteration开始的前一周的周三抛出一个我的设计想法,和中国这边的团队讨论了两天,周五才发邮件给美国的同事,到了周二才正式开会确定采用我的设计,不过架构师要求快速出个原型,还好比较顺利,我的设计还是蛮符合预期的,很多地方甚至比预期的还顺利,根本不用修改代码直接就是OK的。不过,实际上,我们上周还没有把Code Base准备好,开发环境也没有准备好,周五的时候匆忙把Code Base弄好了,下周我还得把我负责的基础类弄好,还有新进的设备得弄好。好多事情啊。估计这个Iteration的BurnDown Chart会很难看,因为上周一周基本上都在做计划外的事情。

设计也不是个简单的事情

理论上,一个系统的设计如果有多种方案,应该是很容易决定出优劣的,但是现实往往不是这样,需要考虑很多种因素。

  • 参与决策的人的设计风格不同,有的喜欢Properties式的无约定扩展风格,有的喜欢超级父类式的运行时多态风格,还有的喜欢根据功能不断增加的API不断对应增加的风格,当然还有其他的一些根据三种风格的变种的风格。
  • 实现系统的人的能力和背景不同,某些很好的设计对于他们来说难度较大,因为实现的人不能充分的理解设计者的意图,最终好的设计变成糟糕的实现。
  • 时间约束,项目的时间很紧,某些设计方案需要做比较多的架构和框架方面的东西才能做业务方面的东西,导致前期更高级别的人看不到项目的直接而且直观的结果。
  • 需求的不确定,很多设计都是根据当前和可预见的需求来设计的,但是如果需求非常的不确定,很难决定那种设计更好,不同的关键需求的变更可能导致某些关键设计的失败。
  • 技术风险,某些设计存在一些技术风险,设计还没有成熟的先例,在大规模系统情况下存在不可预见的技术瓶颈。

Snapshot技术

公司的一个Tech Talk会介绍的备份技术中的一种实现,看到它的实现是使用了Copy On Write,但是和我原来的理解不同,对于我来说,Copy On Write的时候修改的应该是当前版本,因为它是可变的,但是实际上CoW的时候是把Snapshot的那份的逻辑指向修改了(对于我来讲,Snapshot的那份创建完以后应该是只读的,而实际情况不是如此,貌似VMWare的Snapshot技术的实现也是一样的),猜测可能是因为当前版本可能因为有很多其他的进程正在使用中,修改当前版本的指向可能会存在问题,当然,这个问题也是有解决方案的,只是可能由于历史遗留问题导致它的修改不是那么容易,需要更新很多的相关的类库(这个问题在.Net上得到了充分的证明)。

Windows+Apache+PHP5+MYSQL5

打算玩玩Drupal,就搭了个环境,不是很难,但是还是遇到不少问题。
先安装Apache,直接下载Installer安装就行了,没有啥特殊的。
安装MYSQL5,也没有啥特殊的,不过有一点,在Windows下,貌似和Linux下不同,我记得原来linux下mysql的admin用户的用户名是sa,但是在windows下变成root了?还是我记性出错?版本更新?
最后讲PHP,因为问题都是它惹的。
第一,不要下载PHP5.3,因为貌似里面不带php5apache2.dll
第二,下载php5.2的zip包,建议不要下installer,因为网上的文章基本上都是基于zip的
第三,解压到例如c:\php目录下
第四,复制php.ini-dist或者php.ini-recommended为php.ini,修改下php.ini文件,把;extension=php_mysql.dll和;extension=php_mysqli.dll这两行前面的分号去掉
第五,修改httpd.conf,添加如下内容:
LoadModule php5_module "C:/PHP/php5apache2_2.dll"
PHPIniDir "C:/PHP"
AddType application/x-httpd-php .php
AddType application/x-httpd-php .html

注意上面的php5apache2_2.dll,如果你安装的apache是2.0系列的,就是php5apache2.dll
第六,把c:\php和c:\php\ext加入系统的PATH环境变量里面
第七,重启计算机

好了,这个PHP的环境才算搭建好了。
把drupal解压到apache的htdocs下,访问那个install.php就可以了(记得先在mysql下面建个数据库,不需要建任何表)。

使用Checklist提升项目的质量

Checklist这个词是我在做一个日本的外包项目时学到的,问题源于我们最初提交的代码质量非常的差,很多基本的内容编码人员都没有去处理,例如缩进,注释,日志处理,异常处理等,而且由于我们使用的是他们提供的框架,框架本身也有一些要求,到了后来,我们根据以前常见的问题罗列了一个list,而另外抽调了几个人专门根据这个列表进行检查,就演变为checklist,而且这个列表是不断更新的,发现新的共通的错误就加进去,如果有原来的检查项在经过一段时间后几乎就没有再出现过就从列表中删除以减少检查人员不必要的工作。最重要的是这个经验后来被推广到其它的项目组,以及项目的各个阶段,例如需求分析有需求分析的checklist,设计有设计的checklist,即使是测试组也有自己的checklist,因为有些刚刚开始做测试的人对于基本的测试原理并不熟悉,例如边界测试,极大值极小值测试,异常系测试,对于经常被新人忽略的的测试类似就会有一个这样的list,而且每个系统会有一些自己特有的需要特别关注或者以前比较容易出问题的地方,也可以列到这个list里面。这样在整个软件周期中我们可以避免很多常见的问题,大大提升软件的整体质量。

提升项目组的开发效率

通过几年的实际工作,也参与了规模不一的多个项目,但是项目组的开发效率一直不高,一直都在思考这个问题的症结,最近换了一个公司,由于刚刚去,也不能修改比较核心的代码,就给他们修改bug,在修改其中一个比较有共性的问题时接触了很多他们原来写的代码,发现代码中充斥着很多完全相同或者几乎完全相同的代码,最典型的就是获得数据库连接以及关闭数据库连接的代码,有的类会封装一个自己用的方法,有的就是干脆每次重复,有的更是有相关的方法但是代码的其它地方却没有用,这个现象给了我比较大的触动,现在仔细想想,其实影响一个项目组的开发效率的很大的因素就是代码共享和知识共享太缺乏了。但是代码共享和知识共享又确实是比较困难的事情,共通的功能如何使用,需要什么约束条件,能够完成什么功能等等都需要有比较完善的文档,而一旦这样的功能多起来以后你要从这些功能中找到需要的功能有时候确实是比较困难的,特别是有些功能去查是否有现成的代码所花费的时间可能比自己写一个还多。

根据我的经验,有几个地方注意一下就可以比较好的解决: 
 
共通的内容要易于使用和理解,例如定义的方法名要比较贴切。 
要写比较详细的说明文档,例如给大家发邮件或者发布到内部使用的论坛系统中。 
在公布之前经过充分的测试,否则使用的时候总是有各种问题会导致大家不敢再用共通的代码。 
对于类似的功能有其共通的代码,例如使用struts的系统有自己的系统的顶层的BaseAction,在这个BaseAction中定义系统中的子类需要实现的业务逻辑方法入口,而BaseAction要实现structs要求的execute方法,并完成所有的共通任务,例如是否登录的检查,session是否超时等 
业务功能要比较少的关心杂项共通功能,例如定义logger,获取数据库连接,关闭数据库连接,异常处理等,这些功能都可以定义在BaseAction或者是系统的顶层基类中。 
  而且通过使用共通功能也可以很大程度提高系统的质量,因为通过这些年的实践发现,很多新人由于开始不理解系统的要求,很多地方就是先抄袭别人甚至完全拷贝别人的代码,如果别人的代码是有问题的,那么在没有出问题之前是很难被自己发现的,而到了发现的时候已经积重难返了,而通过顶层类的封装,底层的类的空间就狭窄了,犯错误的可能性就小多了,因为很多系统的共通要求在顶层类中已经实现了。

不能浮躁

拿到一个新的任务的时候我们往往马上就开始干,特别是曾经接触过的内容,只要是自己感觉可以做,往往就不管三七二十一开始写代码,现在想想很不应该,拿到新的任务,先要研究一下难度,有没有难点和可能的潜在问题,什么样的方案比较好,灵活性、通用性以及可扩展性方面,另外就是看看系统中是否已经有其它的现成的代码。
每个项目我感觉应该有一个公共的功能库,不光是减轻开发的工作量,对于程序的稳定性,可维护性也是莫大的提高,但是往往有两个问题:
 一、不愿意用别人写的代码,自己总觉得自己的代码比别人好。
 二、不知道怎么用,因为没有文档,这个确实是开发人员的一个通病,喜欢写代码不喜欢写使用文档或者说明文档。

Intellij没有Eclipse好

虽然小胖很喜欢Intellij,并且预言我会喜欢上Intellij,但是用了超过4个月,我并没有喜欢上它,但是也没有像原来那样感觉它太花哨或者难用。公平的讲,Intellij是很不错的,功能做得很完善,特别是代码提示方面,但是似乎仅此而已。从我到现在使用的经验而言,Intellij提供的功能,Eclipse都提供了(有的是插件提供的,Intellij一样),但是在几个方面我感觉Intellij比不上Eclipse。
首先是多个工程,Eclipse下可以打开多个工程,在同一个Eclipse实例里面,但是Intellij只能打开一个工程。
第二就是Hot deploy,Intellij里面也有些插件做这个事情,例如AutoPackage,但是做得不够好,因为修改完代码以后需要保存,在Make Project(CTRL+F9),然后就被自动重新发布了,但是如果装了MyEclipse或者经过简单的配置,在Eclipse下,只需要保存下修改,Eclipse会自动编译并且修改会被发布,这个是JVM支持的功能。
第三就是语法高亮,如果把Eclipse里面的代码拷贝到富文本编辑器,例如Word或者发邮件,拷贝出来的代码是带语法高亮的,Intellij拷贝出来的没有语法高亮

更早的文章 更新的文章

© 2024 解惑

本主题由Anders Noren提供向上 ↑