一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Backend

解决:’ping’ 不是内部或外部命令,也不是可运行的程序

  自从安装了ssh工具后,可爱的ping命令就不能用了,真郁闷…… 然后就把ssh工具卸载了,还是不能用,于是百度~解决。 原因:某些软件把自己添加到环境变量中时,却把系统的环境变量覆盖了,重新把系统的环境变量加上就可以了: %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\system32\WBEM  

龙生   19 Feb 2013
View Details

Windows服务的手动添加和删除方法

    服务,是指执行指定系统功能的程序、例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序。其实,服务就是一种特殊的应用程序,它从服务启动开始就一直处于运行状态,而普通应用程序在运行之后就处于休眠状态,直到用户再次对其进行操作;在WinXP里,服务是在系统加载以后就自动启动的,而不需要登陆,但自动运行的普通应用程序是在WinXP加载并登录以后才执行的。 对于安装服务,一般分为两种情况: 情况一:安装可以作为服务运行的程序成为WinXP的服务; 情况二:安装不可以作为服务运行的程序(即普通的应用程序)成为WinXP的服务。 使用安装工具:srvinstw.exe和srvany.exe,Win2000资源工具包中提供的工具; 下面是手工添加服务的方法,适用找不到添加工具的时候手工添加服务。 通过修改注册表来添加服务: 在注册表编辑器,展开分支“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services”,在右侧窗格中显示的就是本机安装的服务项。如果要新建服务,只须点击“编辑→新建→项”,然后为此项命名,如“test”;然后右击该项,选择“新建→字符串值”或“新建→Dword值”即可。 添加一个服务项目具体需要添加的键值如下: “DisplayName”,字符串值,对应服务名称; “Description”,字符串值,对应服务描述; “ImagePath”,字符串值,对应该服务程序所在的路径; “ObjectName”,字符串值,值为“LocalSystem”,表示本地登录; “ErrorControl”,Dword值,值为“1”; “Start”,Dword值,值为2表示自动运行,值为3表示手动运行,值为4表示禁止; “Type”,Dword值,应用程序对应10,其它对应20。 另外,还要在“test”项下新建一个“Enum”项。如果有些必须通过srvany来加载的还必须添加另外的Parameters子项在该项中提供详细的要加为服务的程序所在的路径。而上面的那个路径就需要指到srvany所在的路径。 上面提到的是如何添加服务,怎么删除windows服务呢,请继续看: 一、Windows服务 Windows服务也称为Windows Service,它是Windows操作系统和Windows网络的基础,属于系统核心的一部分,它支持着整个Windows的各种操作。诸如DNS客户端、打印程序、Windows更新服务、计划任务、Windows时间服务、告警器等服务,它们关系到机器能否正确运行。如果不能适当地管理这些服务,就会影响到机器的正常操作。 一个服务首先是一个Win32可执行程序,或者是是rundll32.exe来运行一个.dll的方式形成的进程。 跟普通应用程序不一样,如打开WORD,有一个界面出来,但服务没有用户界面。也不能通过直接双击运行相应的.exe程序来运行。那Windows又是如何控制一个服务的? Windows的服务由更上一级的services.exe这个服务来管理,由它来管理,负责进行服务的启动、停止、运行,暂停等。我们最常用的操作就是通过Windows的服务MMC界面来完成相关操作。 二、如何删除Windows服务 现在的流氓软件,越来越多把自己注册为一个服务。在Hijackthis的扫描日志中,一般会把非Windows系统的服务以023的方式列出来,如下面这段: O23 – 未知 – Service: BKMARKS [提供传输协议的数据安全保护机制,有效维护数据传输中的安全及完整。] – C:\WINDOWS\SYSTEM32\RUNDLL.EXE O23 – 未知 – Service: ewido anti-spyware 4.0 guard [ewido anti-spyware 4.0 guard] – D:\Program Files\ewido anti-spyware 4.0\guard.exe O23 – 未知 – Service: KSD2Service [KSD2Service] – C:\WINDOWS\system32\SVCH0ST.exe 对于这些流氓软件,需要删除相关的.exe文件,使它不能再运行,或者直接清除这个服务本身,使计算机重启的时候,它不会再启动。 删除的办法有两个: 办法一: 用sc.exe这个Windows命令 开始——运行——cmd.exe,然后输入sc就可以看到了。使用办法很简单:sc delete “服务名”(如sc deleteService 83F9085F) 如针对上面的: sc delete KSD2Service 方法二:直接进行注册表编辑(不推荐) 打开注册表编辑器,找到下面的键值:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,一般服务会以相同的名字在这里显示一个主健,直接删除相关的键值便可。(HKEY_CURRENT_USER\SYSTEM \CurrentControlSet\Services 下可能也有,可在注册表中查找删除) 三、特殊情况 1、如果服务显示的是rundll32.exe,并且这个文件是位于system32目录下,那么就不能删除这个rundll32.exe文件,它是Windows系统的文件。这时只要清除相关的服务就可以了 2、如果一个服务删除了马上又自动建立了,说明后台有进程在监视、保护。需要先在进程管理器中杀掉相应的进程,或者启动后按F8,到安全模式下删除。 转自:http://www.8844.com/html/IT_jiaocheng/ruanjian/chengxu/Windows/system/2011/10-21/378635.html  

龙生   19 Feb 2013
View Details

windows server2008系统开启win7主题和Aero Peek桌面预览(manhaosslove亲测)

  条件:本人使用的是Chew-WGA.0.9破解的server 2008 r2 ,这个能照下面的开启win7主题和aero peek桌面预览 使用SK_Patch_v1_R2_Final破解的是oem完美激活,可惜此windows版本不支持主题 下列是说Chew-WGA.0.9破解的r2办法 1.管理工具—-服务管理器—功能—-添加功能—–打勾桌面体验(安装MediaPlayer和Windows7的功能部件)—-装完重启 2.管理工具—服务—启用Themes服务C:\windows\system32\svchost.exe,以后开启选自动! 3.鼠标右击桌面—个性化—选择使用Aero主题 4.把你的显卡驱动装好才能在性能设置里出现Aero Peek桌面预览题项选,本人使用的是艾尔莎8600GT显卡,不知道是否对显卡要求高不高,不过显卡驱动没装之前高级系统设置里你别想见到此项.哈哈顺手也把声卡驱动也装了,并在服务开启Windows Audio服务,并设置为自动. 5..计算机右击鼠标属性—–高级系统设置—-高级—-性能设置—-自定义—-钩选(启用Aero主题)—-结果在任务栏属性也就可以看到Aero Peek预览桌面是启用可选的. 6.修改Aero Peek桌面预览速度:运行—–cmd—-regedt32—-打开注册表HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced下面新建DWORDS(32位)键值—命名Desktop Livel Preview Hover Time—-键值是500-2000(十进制) PS:已经开启过aero peek桌面预览的,觉得没过动过什么,却突然用不了aero peek了? 或者在高级设置里没法见到aero peek那项 解决办法:个性化—–更改主题重新选取Aero主题—–进去高级设置那就能见到aero peek那项了,点选,开启了aero peek后,你再更改桌面背影,选取多张图片,可以桌面幻灯片10秒—-1天多项选择更换桌面的图片! 转自:http://hi.baidu.com/manhaosslove/item/22d508882a69c85ee63d191d  

龙生   19 Feb 2013
View Details

打开电脑,感觉异常的慢~原来是360,一气之下,卸之

 如题,有图有真相。360自己的流量统计功能,应该不会错吧?我就纳闷了:更新系统补丁,你还要上传?难道360也p2p?!

龙生   19 Feb 2013
View Details

SQL中Case的使用方法

  Case具有两种格式。简单Case函数和Case搜索函数。 –简单Case函数 CASE sex          WHEN ’1′ THEN ’男’          WHEN ’2′ THEN ’女’ ELSE ’其他’ END –Case搜索函数 CASE WHEN sex = ’1′ THEN ’男’          WHEN sex = ’2′ THEN ’女’ ELSE ’其他’ END 这两种方式,可以实现相同的功能。简单Case函数的写法相对比较简洁,但是和Case搜索函数相比,功能方面会有些限制,比如写判断式。 还有一个需要注意的问题,Case函数只返回第一个符合条件的值,剩下的Case部分将会被自动忽略。 –比如说,下面这段SQL,你永远无法得到“第二类”这个结果 CASE WHEN col_1 IN ( ’a', ’b') THEN ’第一类’          WHEN col_1 IN (‘a’)       THEN ’第二类’ ELSE’其他’ END 下面我们来看一下,使用Case函数都能做些什么事情。 一,已知数据按照另外一种方式进行分组,分析。 有如下数据:(为了看得更清楚,我并没有使用国家代码,而是直接用国家名作为Primary Key) 国家(country)人口(population) 中国600 美国100 加拿大100 英国200 法国300 日本250 德国200 墨西哥50 印度250 根据这个国家人口数据,统计亚洲和北美洲的人口数量。应该得到下面这个结果。 洲人口 亚洲1100 北美洲250 其他700 想要解决这个问题,你会怎么做?生成一个带有洲Code的View,是一个解决方法,但是这样很难动态的改变统计的方式。 如果使用Case函数,SQL代码如下: SELECT SUM(population),         CASE country                 WHEN ’中国’     THEN ’亚洲’                 WHEN ’印度’     THEN ’亚洲’                 WHEN ’日本’     THEN ’亚洲’                 WHEN ’美国’     THEN ’北美洲’                 WHEN ’加拿大’ THEN ’北美洲’                 WHEN ’墨西哥’ THEN ’北美洲’         ELSE ’其他’ END FROM    Table_A GROUP BY CASE country                 WHEN ’中国’     THEN ’亚洲’                 WHEN ’印度’     THEN ’亚洲’                 WHEN ’日本’     THEN ’亚洲’                 WHEN ’美国’     THEN ’北美洲’                 WHEN ’加拿大’ THEN ’北美洲’                 WHEN ’墨西哥’ THEN ’北美洲’         ELSE ’其他’ END; 同样的,我们也可以用这个方法来判断工资的等级,并统计每一等级的人数。SQL代码如下; SELECT         CASE WHEN salary <= 500 THEN ’1′              WHEN salary > 500 AND salary <= 600 THEN ’2′              WHEN salary > 600 AND salary <= 800 THEN ’3′              WHEN salary > 800 AND salary <= 1000 THEN ’4′         ELSE NULL END salary_class,         COUNT(*) FROM    Table_A GROUP BY         CASE WHEN salary <= 500 THEN ’1′              WHEN salary > 500 AND salary <= 600 THEN ’2′              WHEN salary > 600 AND salary <= 800 THEN ’3′              WHEN salary > 800 AND salary <= 1000 THEN ’4′         ELSE NULL END; 二,用一个SQL语句完成不同条件的分组。 有如下数据 国家(country)性别(sex)人口(population) 中国1 340 中国2 260 美国1 45 美国2 55 加拿大1 51 加拿大2 49 英国1 40 英国2 60 按照国家和性别进行分组,得出结果如下 国家男女 中国340 260 美国45 55 加拿大51 49 英国40 60 普通情况下,用UNION也可以实现用一条语句进行查询。但是那样增加消耗(两个Select部分),而且SQL语句会比较长。 […]

龙生   19 Feb 2013
View Details

写出高性能SQL语句的十三条法则

  1、 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式。 可见,执行计划并不是固定的,它是“个性化的”。产生一个正确的“执行计划”有两点很重要: (1)    SQL语句是否清晰地告诉查询优化器它想干什么? (2)    查询优化器得到的数据库统计信息是否是最新的、正确的? 2、 统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。 select * from dual select * From dual 其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行! 3、 不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。 一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。 另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,然后再把这一大堆垃圾塞在内存里。可想而知,数据库的效率会何等低下。 4、 使用“临时表”暂存中间结果 简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。 5、 OLTP系统SQL语句必须采用绑定变量 select * from orderheader where changetime > ‘2010-10-20 00:00:01’ select * from orderheader where changetime > ‘2010-09-22 00:00:01’ 以上两句语句,查询优化器认为是不同的SQL语句,需要解析两次。如果采用绑定变量 select * from orderheader where changetime > @chgtime @chgtime变量可以传入任何值,这样大量的类似查询可以重用该执行计划了,这可以大大降低数据库解析SQL语句的负担。一次解析,多次重用,是提高数据库效率的原则。 6、 绑定变量窥测 事物都存在两面性,绑定变量对大多数OLTP处理是适用的,但是也有例外。比如在where条件中的字段是“倾斜字段”的时候。 “倾斜字段”指该列中的绝大多数的值都是相同的,比如一张人口调查表,其中“民族”这列,90%以上都是汉族。那么如果一个SQL语句要查询30岁的汉族人口有多少,那“民族”这列必然要被放在where条件中。这个时候如果采用绑定变量@nation会存在很大问题。 试想如果@nation传入的第一个值是“汉族”,那整个执行计划必然会选择表扫描。然后,第二个值传入的是“布依族”,按理说“布依族”占的比例可能只有万分之一,应该采用索引查找。但是,由于重用了第一次解析的“汉族”的那个执行计划,那么第二次也将采用表扫描方式。这个问题就是著名的“绑定变量窥测”,建议对于“倾斜字段”不要采用绑定变量。 7、 只在必要的情况下才使用begin tran SQL Server中一句SQL语句默认就是一个事务,在该语句执行完成后也是默认commit的。其实,这就是begin tran的一个最小化的形式,好比在每句语句开头隐含了一个begin tran,结束时隐含了一个commit。 有些情况下,我们需要显式声明begin tran,比如做“插、删、改”操作需要同时修改几个表,要求要么几个表都修改成功,要么都不成功。begin tran 可以起到这样的作用,它可以把若干SQL语句套在一起执行,最后再一起commit。好处是保证了数据的一致性,但任何事情都不是完美无缺的。Begin tran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。 可见,如果Begin tran套住的SQL语句太多,那数据库的性能就糟糕了。在该大事务提交之前,必然会阻塞别的语句,造成block很多。 Begin tran使用的原则是,在保证数据一致性的前提下,begin tran 套住的SQL语句越少越好!有些情况下可以采用触发器同步数据,不一定要用begin tran。 8、 一些SQL查询语句应加上nolock 在SQL语句中加nolock是提高SQL Server并发性能的重要手段,在oracle中并不需要这样做,因为oracle的结构更为合理,有undo表空间保存“数据前影”,该数据如果在修改中还未commit,那么你读到的是它修改之前的副本,该副本放在undo表空间中。这样,oracle的读、写可以做到互不影响,这也是oracle广受称赞的地方。SQL Server 的读、写是会相互阻塞的,为了提高并发性能,对于一些查询,可以加上nolock,这样读的时候可以允许写,但缺点是可能读到未提交的脏数据。使用nolock有3条原则。 (1)    查询的结果用于“插、删、改”的不能加nolock ! (2)    查询的表属于频繁发生页分裂的,慎用nolock ! (3)    使用临时表一样可以保存“数据前影”,起到类似oracle的undo表空间的功能, 能采用临时表提高并发性能的,不要用nolock 。 9、 聚集索引没有建在表的顺序字段上,该表容易发生页分裂 比如订单表,有订单编号orderid,也有客户编号contactid,那么聚集索引应该加在哪个字段上呢?对于该表,订单编号是顺序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,这样不容易经常产生页分裂。然而,由于大多数查询都是根据客户编号来查的,因此,将聚集索引加在contactid上才有意义。而contactid对于订单表而言,并非顺序字段。 比如“张三”的“contactid”是001,那么“张三”的订单信息必须都放在这张表的第一个数据页上,如果今天“张三”新下了一个订单,那该订单信息不能放在表的最后一页,而是第一页!如果第一页放满了呢?很抱歉,该表所有数据都要往后移动为这条记录腾地方。 SQL Server的索引和Oracle的索引是不同的,SQL Server的聚集索引实际上是对表按照聚集索引字段的顺序进行了排序,相当于oracle的索引组织表。SQL Server的聚集索引就是表本身的一种组织形式,所以它的效率是非常高的。也正因为此,插入一条记录,它的位置不是随便放的,而是要按照顺序放在该放的数据页,如果那个数据页没有空间了,就引起了页分裂。所以很显然,聚集索引没有建在表的顺序字段上,该表容易发生页分裂。 曾经碰到过一个情况,一位哥们的某张表重建索引后,插入的效率大幅下降了。估计情况大概是这样的。该表的聚集索引可能没有建在表的顺序字段上,该表经常被归档,所以该表的数据是以一种稀疏状态存在的。比如张三下过20张订单,而最近3个月的订单只有5张,归档策略是保留3个月数据,那么张三过去的15张订单已经被归档,留下15个空位,可以在insert发生时重新被利用。在这种情况下由于有空位可以利用,就不会发生页分裂。但是查询性能会比较低,因为查询时必须扫描那些没有数据的空位。 重建聚集索引后情况改变了,因为重建聚集索引就是把表中的数据重新排列一遍,原来的空位没有了,而页的填充率又很高,插入数据经常要发生页分裂,所以性能大幅下降。 对于聚集索引没有建在顺序字段上的表,是否要给与比较低的页填充率?是否要避免重建聚集索引?是一个值得考虑的问题! 10、加nolock后查询经常发生页分裂的表,容易产生跳读或重复读 加nolock后可以在“插、删、改”的同时进行查询,但是由于同时发生“插、删、改”,在某些情况下,一旦该数据页满了,那么页分裂不可避免,而此时nolock的查询正在发生,比如在第100页已经读过的记录,可能会因为页分裂而分到第101页,这有可能使得nolock查询在读101页时重复读到该条数据,产生“重复读”。同理,如果在100页上的数据还没被读到就分到99页去了,那nolock查询有可能会漏过该记录,产生“跳读”。 上面提到的哥们,在加了nolock后一些操作出现报错,估计有可能因为nolock查询产生了重复读,2条相同的记录去插入别的表,当然会发生主键冲突。 11、使用like进行模糊查询时应注意 有的时候会需要进行一些模糊查询比如 select * from contact where username like ‘%yue%’ 关键词%yue%,由于yue前面用到了“%”,因此该查询必然走全表扫描,除非必要,否则不要在关键词前加%, 12、数据类型的隐式转换对查询效率的影响 sql server2000的数据库,我们的程序在提交sql语句的时候,没有使用强类型提交这个字段的值,由sql server 2000自动转换数据类型,会导致传入的参数与主键字段类型不一致,这个时候sql server 2000可能就会使用全表扫描。Sql2005上没有发现这种问题,但是还是应该注意一下。 13、SQL Server 表连接的三种方式 (1) Merge Join (2) Nested Loop Join (3) Hash Join SQL Server 2000只有一种join方式——Nested Loop Join,如果A结果集较小,那就默认作为外表,A中每条记录都要去B中扫描一遍,实际扫过的行数相当于A结果集行数x B结果集行数。所以如果两个结果集都很大,那Join的结果很糟糕。 SQL Server 2005新增了Merge Join,如果A表和B表的连接字段正好是聚集索引所在字段,那么表的顺序已经排好,只要两边拼上去就行了,这种join的开销相当于A表的结果集行数加上B表的结果集行数,一个是加,一个是乘,可见merge join 的效果要比Nested Loop Join好多了。 如果连接的字段上没有索引,那SQL2000的效率是相当低的,而SQL2005提供了Hash join,相当于临时给A,B表的结果集加上索引,因此SQL2005的效率比SQL2000有很大提高,我认为,这是一个重要的原因。 总结一下,在表连接时要注意以下几点: (1)    连接字段尽量选择聚集索引所在的字段 (2)    仔细考虑where条件,尽量减小A、B表的结果集 (3)    如果很多join的连接字段都缺少索引,而你还在用SQL Server 2000,赶紧升级吧。 原文链接:http://www.cnblogs.com/shuzhengyi/archive/2011/02/12/1952481.html

龙生   19 Feb 2013
View Details

SQL server的一道入门面试题背后的思考

  最近看到一个SQL Server的小例子,发现完全可以作为SQL server的一道入门面试题。题目如下: 例:有一合同表Contract Id Name Total buget 1 合同名称 100  102,22 2 合同名称2 300 ,102,22, 3 合同名称3 200  103,23, 要求:用SQL语句更新表的buget字段,如果前后没有”,”要加上”,”(即一个英文逗号)。(10分) 创建表数据: View Code use Testdb2 go IF NOT OBJECT_ID(‘[Contract]‘) ISNULL DROPTABLE [Contract] GO Createtable [Contract] (ID intprimarykey identity(1,1) ,[Name] nvarchar(50) null ,Total floatnull ,buget Nvarchar(500) null ) go insertinto [Contract] select‘合同名称’,  100,’102,22′ unionall select‘合同名称2′, 300,‘,102,22,’ unionall select‘合同名称3′, 300,’101,23,’  分析:这道题乍看很简单,由于肯定用到Replace,所以很自然的结合left,right,从而得到以下语句 方法一: update [Contract] set buget=‘,’+buget whereleft(buget,1)=‘,’ update [Contract] set buget=buget+‘,’whereright(buget,1)=‘,’ 如果能写成一个 SQL语句,可以加1分。 update [Contract] set buget=(casewhen (left(buget,1)!=‘,’andright   (buget,1)!=‘,’) then‘,’+buget+‘,’ whenleft(buget,1)!=‘,’then‘,’+buget whenright(buget,1)!=‘,’then  buget+‘,’ else buget end) 如果能从字符串的开关和结尾这个思路出发,结合Reverse,可以提到如下方法: 方法二: update [Contract] set buget=‘,’+buget where charindex(‘,’,buget)<>1 update [Contract] set buget=buget+‘,’where charindex(‘,’,reverse(buget))<>1 该方法,主要涉及charindex函数和reverse函数。 说实话,我当时就这两种思路,这也是SQL中常见的基本用法。但出人意料的第三种方法出现了。 方法三: UPDATE [contract] SET Buget = ‘,’+Buget+‘,’ UPDATE [contract] SET Buget = REPLACE(Buget,‘,,’,‘,’) 解析:该方法最主要的亮点不在于语法的精妙,而在于其思路的异于常规。先给两边补上逗号,再替换双逗号为单逗号。这在实际编程中确实难能可贵。换句话说,如果没有事先思考过的话,这反映了解题者反应敏捷,思路开放。因此,至少可以再加3分。 当然,此语句其实还是有bug,比如如果原bug字段中间有两个逗号,那么在Replace时就会更新掉不应该更新的内容。不过,稍加修正,限定replace的范围即可, 受此思路启发,可以引申得到以下类似方法: 方法四: UPDATE [contract] SET Buget = substring(BuGet,2,len(BuGet)-1) wherecharindex(‘,’,buget)=1 UPDATE [contract] SET Buget = substring(BuGet,1,len(BuGet)-1) wherecharindex(‘,’,reverse(buget))=1 UPDATE [contract] SET BuGet = ‘,’+BuGet+‘,’ 该方法是先去掉两边的逗号,再给每条记录加上逗号,比起方法三来,稍显繁琐,这也反衬了方法三的巧妙。 当然,也可以结合前面的思路稍作修正,这里就不再赘述,请读者自己思考。 感悟:释迦牟尼说过“人生需要经过六项修炼:布施、持戒、忍辱、精进、禅定、智慧。”,SQL编程,或C#、Java,甚至Javascrip的某个领域也是如此。技术是死的,思路是鲜活的,有时候,思路能轻易地突破技术很难实现的死角。到了一定程度时,会发现潜意识里已经被惯性思维塞满,而无法接受新鲜思维方式或思路,如果一段时间内持续如此,那么,我们应该警醒,把自己的头脑放空,把自己置于一个初学者的地位,重新开始“精进”的修炼! 原文链接:http://www.cnblogs.com/downmoon/archive/2011/03/02/1968615.html  

龙生   19 Feb 2013
View Details

面试题:一道冒泡算法笔试题的演进史

  给定N个整数,请使用冒泡算法按照从大到小的顺序排序 1.可对N个整数的某一段(连续的M整数)排序  2.要求具有一定的可测试性 3.C#语言  ——————-- 思路: 1.冒泡算法 2.针对部分排序 3.可测试性 先上一段最简单的代码实现冒泡算法--这里错误的使用了选择排序,请参看改进版本的修正 int[] list= new int[] {1, 2, 3, 4, 5};         for (int i=0;i<list.Length;i++)             for (int j=i+1;j<list.Length;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         for (int i=0;i<list.Length;i++)             System.Console.Write("{0}\t",list[i]);         System.Console.WriteLine(""); 观看上述代码,有如下发现 1)行1,主要进行数据的初始化工作,准备数据  2)行2-11,主要实现冒泡排序算法 3)行12-14,主要是显示结果 4)行1-14,包含算法实现,调用,实现和使用糅合在一起 第一次改进: 1)数据初始化部分,其实属于调用部分,此时用的是数组,扩展性较差,这里改成List<int>,并将此步重构成函数 //初始化N个数据void Init(List<int> list,int count){    System.Random a=new Random();    for (int i=0;i<count;i++)        list.Add(a.Next(100));} 这里初始化数据,主要是减少人工干预,自动产生测试数据,实际生产过程中,是需要按照实际情况,选取一些比较特殊的数据作为测试数据的. 2)冒泡排序算法实现过程部分,也可以重构成函数 //实现冒泡算法——这里错误的使用了选择排序     void Bubble(List<int> list)     {                 for (int i=0;i<list.Count;i++)             for (int j=i+1;j<list.Count;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         } 正确的冒泡排序为 void Bubble(List<int> list)     {         bool bFlag=false;         for (int i=0;i<list.Count;i++)         {             bFlag=false;             for(int j=list.Count-1-1 ;j>i-1;j--)             {                 if (list[j]<list[j+1])                 {                     int tmp=list[j+1];                     list[j+1]=list[j];                     list[j]=tmp;                     bFlag=true;                 }             }             if (!bFlag) break;         }     }     将排序的代码,重构成函数,使得算法可以非常容易进行测试,只需要将精心设计的测试数据传给函数,就可以了 3)显示结果,也是重构成函数 //显示结果 void Print(List<int> list) {     for (int i=0;i<list.Count;i++)         System.Console.Write("{0}\t",list[i]);     System.Console.WriteLine(""); } 4)最终调用过程 public static void Main(){    List<int> list=new List<int>();    //产生测试数据    Init(list,8);        //打印测试数据    Print(list);        //按照从大到小的顺序排序    Bubble(list);    //打印排序后的结果    Print(list);    }  第二次改进: 第一次改进中,基本解决冒泡算法和可测试性的问题,但是还有一个重要问题没有解决,就是针对N个整数中的某一段连续M个数据进行排序,所以这次的改进主要集中在<冒泡排序算法实现>函数的改进 很明显,要实现这个功能,只需要,在 Bubble这个函数增加两个参数,标识出M的上下限,Bubble变成如下形式

新的实现(注意,这里我的冒泡算法的实现是不对的,我用的是选择排序,经过一个园子里的兄弟提醒,我查过资料,发现的确用错了) 选择排序(Selection sort) 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。 void Bubble(List<int> list,int low,int high){    int iHigh= list.Count<high+1? list.Count : high+1 ;    int iLow=low<0? 0 :low ;    //System.Console.WriteLine("{0}\t{1}",iLow,iHigh);    for (int i=iLow;i<iHigh;i++)        for (int j=i+1;j<iHigh;j++)        {                            if (list[i]<list[j])//比较不一定相邻            {                int tmp=list[i];                list[i]=list[j];                list[j]=tmp;            }        }    } 下面是更正后的冒泡排序代码 冒泡排序(BubbleSort) 依次比较相邻的两个数,将小数放在前面,大数放在后面。 static void Bubble(List<int> list,int low,int high)     {         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;                  bool bFlag=false;         for (int i=iLow;i<iHigh;i++)         {             bFlag=false;             for(int j=iHigh-1-1 ;j>i-1;j--)             {                 if (list[j]<list[j+1])//比较相邻                 {                     int tmp=list[j+1];                     list[j+1]=list[j];                     list[j]=tmp;                     bFlag=true;                 }             }             if (!bFlag) break;         }         }   并提供一个重载函数

调用: public static void Main() {     List<int> list=new List<int>();     //产生测试数据     Init(list,8);         //打印测试数据     Print(list);         //按照从大到小的顺序排序,针对序号2-5的之间的数据     Bubble(list,2,5);     //打印排序后的结果     Print(list);  } 至此,题目要求的目的全部达到,不过还是少了点什么,下面进行第三次改进 第三次改进: 第一次改进和第二次改进的结果,还是采用面向过程的方法,第三次改进侧重与面向对象的方法,就是封装 三个主要函数中都有List<int> list参数,这个是主要数据,我们用类来封装它,如下给出完整代码 public class BubbleSort {     List<int> _list;     public BubbleSort()     {         _list=new List<int>();     }     public BubbleSort(List<int> list)     {         _list=list;     }          public void Sort()     {                 Sort(    _list,0,_list.Count-1);             }         public void Sort(int low,int high)     {         Sort(    _list,low,high);     }     //实现冒泡算法--这里错误使用选择排序,请替换为第二次改进中的正确实现      public void Sort(List<int> list,int low,int high)     {         //int iHigh= list.Count<low+count? list.Count : high ;         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;         //System.Console.WriteLine("{0}\t{1}",iLow,iHigh);         for    (int i=iLow;i<iHigh;i++)             for    (int j=i+1;j<iHigh;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         }                  //初始化N个数据     public void Init(int count)     {         _list.Clear();         System.Random a=new Random();         for    (int i=0;i<count;i++)             _list.Add(a.Next(100));     }     //显示结果     public  void Print(List<int> list)     {         Print(list,0,list.Count-1,true);     }     public  void Print(List<int> list,int low,int high,bool IsNewLine)     {         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;                  for    (int i=iLow;i<iHigh;i++)             System.Console.Write("{0}\t",list[i]);         if (IsNewLine)             System.Console.WriteLine("");     }     public void Print(int low,int high,bool IsNewLine)     {         Print(_list,low,high,IsNewLine);     }     //将排序的M个数据用红色显示     public void Print(int low,int high)     {         Print(0,low-1,false);         System.Console.ForegroundColor=ConsoleColor.Red;         Print(low,high,false);                 System.Console.ResetColor();         Print(high+1,_list.Count,true);     }          public void Print()     {         Print(_list);     }     //for test     public void Test()     {         //产生测试数据         Init(10);             //打印测试数据         Print();             //按照从大到小的顺序排序         int[] iLowHigh=new int[]{4,7};         Sort(iLowHigh[0],iLowHigh[1]);         //Sort(-1,8);         //Sort(0,18);         //Sort(-1,18);         //打印排序后的结果         //Print();          Print(iLowHigh[0],iLowHigh[1]);          } } 调用代码:

 

龙生   20 Nov 2012
View Details

iis 6.0 http转向 https(很简单)

  在网上找了好多资料都没找到,无意当中找的了一片文章(国外的网站)帮我解决了问题,因此想与大家分享。 首先错误信息(见图一): 图一 解决方法: 一、验证SSL需要选中的网站(见图二) 1、首先打开所要修改的网站然后右击选择“属性” 2、选择“目录安全性”-->在安全通信中选择“编辑” 3、选择“要求安全通信(SSL)”后点击“确定”。   图二 二、创建一个HttpRedirect.htm 文件保存到“C:\InetPub” HttpRedirect.htm中的代码:

  三、用HttpRedirect.htm文件替换403文件(见图三) 1、打开你的网站右击选择“属性” 2、选择“自定义错误”点击编辑 3、在“文件”中添加HttpRedirect.htm文件(路径为:C:\Inetpub\HttpRedirect.htm) 图三 四、测试 输入的网址:http://会自动跳转到https://   参考网址: http://www.jppinto.com/2009/01/automatically-redirect-http-requests-to-https-on-iis-6/   转自:http://www.cnblogs.com/nanyaxu/archive/2012/11/19/2777507.html

龙生   20 Nov 2012
View Details

Windows7安装OpenSSH

OpenSSH很老了,所以… 最开始只是因为openSSH启动不了,才用的MobaSSH,它配置简单兼容性好,缺点就是偷偷的建立了一个账户,让我感觉很不爽。所以决定把OpenSSH配置好。经过检查,发现OpenSSH安装的时候已经把环境变量添加好了,因此在命令行窗口是可以直接输入执行 ssh chmod等等命令的,但是当我输入ls的时候,提示缺少cygintl-2.dll,所以这个提醒了我更换检索词。最终解决这个问题。 下载地址: http://sourceforge.net/projects/sshwindows/files/OpenSSH for Windows – Release/3.8p1-1 20040709 Build/setupssh381-20040709.zip/download 1. 默认安装 2. 补上cygintl-2.dll和cygwin1.dll 下载:http://samanthahalfon.net/resources/cygwin_includes.zip 将它们复制到c:\Program Files (x86)\OpenSSH\bin目录下,如果提示覆盖,则覆盖之,不然进行下面操作,会提示 不能启动opensshd服务 OpenSSH Error 1067:The process terminated unexpectedly 系统出错,进程意外终止 3. 开始安装 cd "c:\Program Files (x86)\OpenSSH\bin" mkgroup -l >> ..\etc\group 生成一个group mkpasswd -l [-u <username>] >> ..\etc\passwd 比如: mkpasswd -l -u mxio >> ..\etc\passwd 这样就生成用户名mxio的passwd文件, 它调用的是系统用户名和密码 cd ..\..\etc 给权限..\bin\chown mxio * ..\bin\chmod 600 * 4. 启动opensshd服务 不出问题会提示启动成功 net start opensshd 5. 测试连接 ssh mxio@localhost

龙生   19 Nov 2012
View Details
1 256 257 258 279