2006年05月11日

 

 

 精彩的主题:
1、Mostly Crystal

2、SphereGnome

3、Qute

更多…………

丰富的扩展:
1、Google Tool Bar  强大的搜索,还有拼写检查和取词翻译,金山词霸可以省了。

 2、Html Validator  HTML验证器,检测HTML标签的。

3、Sun Cult   显示世界各地的日出日落,月出月落的时间。

更多…….

2006年04月27日

很早就开始用DisplayTag了,真得很方便,不用考虑分页,表格等问题。

但是有一个问题一直困扰我,就是有中文作为表单提交内容的时候,翻页就不能用了,中文变成了乱码。

表单传送时, form的提交采用的是Post方法,这没错,但链接采用的是Get方法,问题就出在这里,因为和Tomcat4相比,Tomcat5的post和get采用的方式不再相同了,汉字编码的实现方式也不同了。

Post是将地址传送一次,将form的数据单独提交,而Get则是将地址和参数一起传送,传送的不止是form的数据。

 默认情况下,Tomcat对请求采用的默认编码是ISO-8859-1,这样我们提交的汉字被认为是ISO-8859-1的编码,所以在程序中接收时显示乱码。  在过滤器中调用request.setCharacterEncoding("GBK"),那么Post上来的汉字将被认为是GBK编码,而Tomcat5对于Get请求上来的编码并不根据过滤器的设定辨认编码方式,默认的依然是ISO-8859-1,所以,即使你的页面使用默认的编码方式进行编码,然后使用ISO-8859-1进行解码,得到的结果也不对

解决方法:
在Server.xml的connector部分设定URIEncoding的值,根据编码方式指定自己的值就可以了
例如:URIEncoding="GB2312"

 


2006年04月26日

操作符优化

[被屏蔽广告]    IN 操作符

    用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。

    但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

    ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。

    推荐方案:在业务密集的SQL当中尽量不采用IN操作符。

    NOT IN操作符

    此操作是强列推荐不使用的,因为它不能应用表的索引。

    推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替

    <> 操作符(不等于)

    不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

    推荐方案:用其它相同功能的操作运算代替,如

    a<>0 改为 a>0 or a<0

    a<>’’ 改为 a>’’

    IS NULL 或IS NOT NULL操作(判断字段是否为空)

    判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。

    推荐方案:

    用其它相同功能的操作运算代替,如

    a is not null 改为 a>0 或a>’’等。

    不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。

    建立位图索引(有分区的表不能建,位图索引比较难控制,如字段值太多索引会使性能下降,多人更新操作会增加数据块锁的现象)

    > 及 < 操作符(大于或小于操作符)

    大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100万记录,一个数值型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了,因为A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。

    LIKE操作符

    LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

一、问题的提出
在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性。

在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。

二、SQL语句编写注意问题
下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。

1. IS NULL 与 IS NOT NULL
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。

任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

2. 联接列

对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。我们一起来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),现在要查询一个叫比尔.克林顿(Bill Cliton)的职工。

下面是一个采用联接查询的SQL语句,

select * from employss
where
first_name||”||last_name =’Beill Cliton’

上面这条语句完全可以查询出是否有Bill Cliton这个员工,但是这里需要注意,系统优化器对基于last_name创建的索引没有使用。

当采用下面这种SQL语句的编写,Oracle系统就可以采用基于last_name创建的索引。

Select * from employee
where
first_name =’Beill’ and last_name =’Cliton’

遇到下面这种情况又如何处理呢?如果一个变量(name)中存放着Bill Cliton这个员工的姓名,对于这种情况我们又如何避免全程遍历,使用索引呢?可以使用一个函数,将变量name中的姓和名分开就可以了,但是有一点需要注意,这个函数是不能作用在索引列上。下面是SQL查询脚本:

select * from employee
where
first_name = SUBSTR(‘&&name’,1,INSTR(‘&&name’,’ ‘)-1)
and
last_name = SUBSTR(‘&&name’,INSTR(‘&&name’,’ ‘)+1)

3. 带通配符(%)的like语句

同样以上面的例子来看这种情况。目前的需求是这样的,要求在职工表中查询名字中包含cliton的人。可以采用如下的查询SQL语句:

select * from employee where last_name like ‘%cliton%’

这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串其他位置时,优化器就能利用索引。在下面的查询中索引得到了使用:

select * from employee where last_name like ‘c%’

4. Order by语句

ORDER BY语句决定了Oracle如何将返回的查询结果排序。Order by语句对要排序的列没有什么特别的限制,也可以将函数加入列中(象联接或者附加等)。任何在Order by语句的非索引项或者有计算表达式都将降低查询速度。

仔细检查order by语句以找出非索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by子句中使用表达式。

5. NOT

我们在查询时经常在where子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用and(与)、or(或)以及not(非)。NOT可用来对任何逻辑运算符号取反。下面是一个NOT子句的例子:

… where not (status =’VALID’)

如果要使用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符。NOT运算符包含在另外一个逻辑运算符中,这就是不等于(<>)运算符。换句话说,即使不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例:

… where status <>’INVALID’

再看下面这个例子:

select * from employee where salary<>3000;

对这个查询,可以改写为不使用NOT:

select * from employee where salary<3000 or salary>3000;

虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。

6. IN和EXISTS

有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种格式的子查询。

第一种格式是使用IN操作符:

… where column in(select * from … where …);

第二种格式是使用EXIST操作符:

… where exists (select ‘X’ from …where …);

我相信绝大多数人会使用第一种格式,因为它比较容易编写,而实际上第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。

第二种格式中,子查询以‘select ‘X’开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化器就不必遍历整个表而仅根据索引就可完成工作(这里假定在where语句中使用的列存在索引)。相对于IN子句来说,EXISTS使用相连子查询,构造起来要比IN子查询困难一些。

通过使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。

同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。

2006年04月04日

Google Page Creator 可以在线建立网页了,界面很简单,功能不多,但都是基本的网页功能,现在还是在测试阶段,我记得以前也有类似的提供在线编辑网页的网站,不知道这次Google会给咱们带来什么。

我在Google Page Creator 上建立的简单的网页:http://lveyoly.googlepages.com/home

2006年04月01日


IT工作市场是如此的紧张,每个可获得的职位都有一堆人在申请。Naveen Nahata为Oracle E-Business Suite的数据库管理员申请者提供了以下一些面试时的技术问题,它可以帮助申请者们快速脱颖而出。如果你的面试官有类似的问题问你,发个邮件给我,我将会把它添加在列表中。――编者按

  问题

  1如果信息采集管理系统(ICM)崩溃了怎么办?

  2你如何加速打补丁的过程?

  3打补丁的过程中出错了,你怎么办?

  4请提供克隆过程和克隆之后采取的手工操作的大概步骤。

  5介绍一下AutoConfig。AutoConfig是如何知道XML文件中的哪个树脂需要被放入哪一个文件的?

  6你能告诉我,你对一个发生故障的自服务登录问题做哪些测试吗?你要检查哪个配置文件操作选项和文件?

  7如果你不能看到并发管理日志和输出文件,是哪里出错了?

  8你是如何更改并发管理日志和输出文件的位置的?

  9如果用户正遇到性能方面的问题,你如何找到问题的原因?

  10你如何更改应用程序的密码?

  11请写出DBC文件的位置,并且解释它的重要性和应用程序如何知道DBC文件名?

  答案

  1所有其他的管理器都会继续工作。ICM只会处理队列控制请求,意思是开启和关闭其他并发的管理器。

  2

  2.1你可以合并多个补丁。

  2.2你可以为一个非交互的补丁创建一个响应文件。

  2.3你可以通过选项(nocompiledb, nomaintainmrc, nocompilejsp)来应用补丁,并且在应用了所有的补丁之后,一次运行它们。

  3 查看失败工作的日志,找到并且纠正错误,用adctrl 工具重新开启工作。

IT工作市场是如此的紧张,每个可获得的职位都有一堆人在申请。Naveen Nahata为Oracle E-Business Suite的数据库管理员申请者提供了以下一些面试时的技术问题,它可以帮助申请者们快速脱颖而出。如果你的面试官有类似的问题问你,发个邮件给我,我将会把它添加在列表中。――编者按

  问题

  1如果信息采集管理系统(ICM)崩溃了怎么办?

  2你如何加速打补丁的过程?

  3打补丁的过程中出错了,你怎么办?

  4请提供克隆过程和克隆之后采取的手工操作的大概步骤。

  5介绍一下AutoConfig。AutoConfig是如何知道XML文件中的哪个树脂需要被放入哪一个文件的?

  6你能告诉我,你对一个发生故障的自服务登录问题做哪些测试吗?你要检查哪个配置文件操作选项和文件?

  7如果你不能看到并发管理日志和输出文件,是哪里出错了?

  8你是如何更改并发管理日志和输出文件的位置的?

  9如果用户正遇到性能方面的问题,你如何找到问题的原因?

  10你如何更改应用程序的密码?

  11请写出DBC文件的位置,并且解释它的重要性和应用程序如何知道DBC文件名?

  答案

  1所有其他的管理器都会继续工作。ICM只会处理队列控制请求,意思是开启和关闭其他并发的管理器。

  2

  2.1你可以合并多个补丁。

  2.2你可以为一个非交互的补丁创建一个响应文件。

  2.3你可以通过选项(nocompiledb, nomaintainmrc, nocompilejsp)来应用补丁,并且在应用了所有的补丁之后,一次运行它们。

  3 查看失败工作的日志,找到并且纠正错误,用adctrl 工具重新开启工作。

4在源文件上(所有层)运行pre-clone,使用RMAN复制数据库(或者从热或者冷备份中重新存储数据库),拷贝文件系统,然后在目标文件(所有层)上运行post-clone 。

  手工步骤(可能会更多):

  4.1改变所有的非网站配置选项数值(快速克隆的话,只改变网站级别的配置文件选项)。

  4.2 修改工作流和并发管理器表。

  4.3更改打印机。

  5 AutoConfig 使用了一个上下文文件来维护关键的配置文件。一个上下文文件就是一个XML文件,在$APPL_TOP/admin 目录下,进行集中式的存储。

  当你运行AutoConfig 的时候,它读取XML文件,并且创建所有的AutoConfig 管理配置文件。

  对于AutoConfig维护的每个配置文件,都存在一个临时文件来判断哪个数值是从哪个XML文件中得来的。

  6

  6.1检查DBC文件中的guest的用户名和密码,配置选项guest的用户名和密码、数据库。

  6.2查看apache/jserv是否启动了。

  6.3运行IsItWorking, FND_WEB.PING, aoljtest等。

  7很有可能是FNDFS监听器停止了。看看FND_CONCURRENT_REQUESTS 表中的OUTFILE_NODE_NAME 和 LOGFILE_NODE_NAME 的数值。看看FND_NODES 表。看看tnsnames.ora 中的FNDFS_ entry 。

  8日志问卷爱女的位置是由$APPLCSF/$APPLLOG 参数来决定的,输出文件的位置是由$APPLCSF/$APPLOUT 决定的。

  9

  9.1追踪这个会话(用等待)并且使用tkprof 来分析追踪文件。

  9.2生成statspack 报告并进行分析。

  9.3使用top/iostat/sar/vmstat 监控O/s 。

  9.4通过ping这类基本的测试结果来判断网络的瓶颈。

  10

  10.1 使用FNDCPASS 来更改APPS密码。

  10.2 手工修改wdbsvr.app/cgiCMD.dat 文件。

  10.3 更改所有从其他环境指过来的数据库链接。

  11

  11.1位置:$FND_TOP/secure directory

  11.2 重要性:在其他事务中指向数据库服务器。

  11.3 应用程序通过使用“Applications Database Id.”来了解DBC文件的名字。


Google

      AJAX (asynchronous JavaScript and XML)技术快速的在几周内从网络BLOG到华尔街日报蔓延开来,使开发者认为这将意味着桌面应用程序的灭亡。当然它中存在一个实事的核心就是:最近这些在AJAX大旗下开发的新WEB程序已经给一种能给最终用户提供平滑滚动,不断更新和更具互动性的输入表单的浏览器重新下了定义。

       但是,所谓的肥客户端UI同WEB形式的UI相比,还是保持着一个基本的优点,就是实时的事件响应。单独的AJAX不能处理IM,股票报价,和其他的需要“PUSH”数据流的协作应用。

       AJAX方式应用的主要目标就是将一个新的WEB页面分成一系列的更小的,使用更频繁的信息交换来下载。开发者认为AJAX是“异步的”,因为数据可以在不影响用户操作的情况下更新。例如:GOOGLE MAPS就是应用下载新的可视部分并且移动剩下的部分而减少用户滚动页面所等待的时间。

      然而,在中间件社区中,异步的正式定义就是在任一端,任一时间发送一个消息的能力。AJAX提供了逆流的方向,但是HTTP似乎使初始化服务器传送不能完成。

      幸运的是,智慧的开发者利用了HTML中的一个漏洞处理它。浏览器是为了显示在从慢速网站下载不断增长的网页而设计的。应用隐藏框架和javascript标签,HTTP可以保持打开一个长久的连接响应,允许一个应用将数据传到浏览器。

      开发这个的最简单的途径就是将浏览器换为21世纪的“green screen”傻终端。Manuel Kiessling的开源项目ARSC(A Really Simple Chat)使用AJAX技术来发送输入行,而一个更改的HTTP服务器处理打开上千个同步的连接来转播聊天数据给其他用户。另外一个例子是KnowNow的SpeedReader产品,就是用来提醒雇员相关的RSS新闻条目的。

      AJAX和异步事件响应的结合的更广泛的意义在于扩展了跨Internet发布与订阅应用的集成。

      几个开源平台提供把企业应用和WEB服务同交互WEB UI完全连接起来的强大功能。Nevow 和 Pushlets分别扩展Python和Java相似于MVC的事件循环。Mod_PubSub是作为一个用URL路径名作为主题来出发程序的事件总线而设计的,Mod_PubSub也是用多个语言编写的。商业上,KnowNow的LiveServer提供企业级类的扩充(甚至可以和Excel互相连接)。

      从桌面应用程序迁移到WEB应用明显的优点在于维护性,安全性和扩充性方面,但是也必须考虑反应时间较慢的代价,有限的交互,以及不够漂亮的图像界面。有了AJAX,PUSH技术,和普遍存在的PDF和Flash插件,WEB比以往任何时候更加接近成为一个可行的默认应用程序开发平台.

 By  Rohit Khare
May 23, 2005
原文:http://www.infoworld.com/article/05/05/23/21FEwebapppush_1.html 


Google

2006年03月30日

下载的zip版的tomcat要注册为windows系统服务就要运行bin/service.bat
加载服务为
service install tomcat5
卸载服务为
service remove tomcat5

可以对service.bat文件做一些其他修改,使tomcat更加能满足我们各种不同需求时的要求

1. 如果让tomcat编译jsp文件,就在PR_CLASSPATH中加入J2SDK的tools.jar
修改前:
set PR_CLASSPATH=%CATALINA_HOME%\bin\bootstrap.jar
修改后:
set PR_CLASSPATH=%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\bin\bootstrap.jar

2.要使用一个特定的JVM,就要修改jvm的参数;要使注册的windows服务的启动方式为自动,增加–Startup Automatic,这个是比较常用的;要用定制的server.xml配置文件并且传递多个参数给StartClass,要修改StartParams的值,各个值之间用分号分隔:
修改前:
"%EXECUTABLE%" //IS//%SERVICE_NAME% –Jvm auto
–StartClass org.apache.catalina.startup.Bootstrap –StopClass org.apache.catalina.startup.Bootstrap
–StartParams start –StopParams stop
修改后:
"%EXECUTABLE%" //IS//%SERVICE_NAME% –Jvm "%JAVA_HOME%\jre\bin\server\jvm.dll"
–StartClass org.apache.catalina.startup.Bootstrap –StopClass org.apache.catalina.startup.Bootstrap
–StartParams "-config;%CUSTOM_SERVERXML_FILE%;-nonaming;start" –StopParams stop
–Startup Automatic

3. 指定最大和最小的内存限制,要增加jvm的初始参数
修改前:
"%EXECUTABLE%" //US//%SERVICE_NAME% –JvmOptions
"-Dcatalina.base=%CATALINA_BASE%;-Dcatalina.home=%CATALINA_HOME%;-Djava.endorsed.dirs=%CATALINA_HOME%\common\endorsed"
–StartMode jvm –StopMode jvm

修改后:
"%EXECUTABLE%" //US//%SERVICE_NAME% –JvmOptions
"-Xms128M;-Xmx256M;-Dcatalina.base=%CATALINA_BASE%;-Dcatalina.home=%CATALINA_HOME%;-Djava.endorsed.dirs=%CATALINA_HOME%\common\endorsed"
–StartMode jvm –StopMode jvm

4.有时注册windows服务成功后,但是启动服务时显示“发生服务特定错误: 0.”
就是因为jvm没有指定,修改Jvm auto为Jvm "%JAVA_HOME%\jre\bin\server\jvm.dll"后重新注册windows服务就可以启动了。

2006年03月27日

将 Tocmat5.0 注册为 Windows 的服务程序

步骤:
1、下载 Tomcat 5.0.x(不要下载安装版本);
2、解压到 %TOMCAT_HOME% ;
3、安装或者从别处拷贝JRE(推荐拷贝,可以删除不需要的文件,如文档等);
4、在 %TOMCAT_HOME%\bin 目录下运行以下命令将 Tomcat5.0 注册为服务程序和启动服务:
 注册:service install (可以加上自定义服务名称,默认是 Tomcat5 )
 卸载:service remove (可以加上自定义服务名称,默认是 Tomcat5 )
 启动: net start Tomcat5 (或自定义的服务名称)
 停止:net stop Tomcat5(或自定义的服务名称)

说明:
 启动和停止命令可以在任意目录下运行。


注意事项:
1、Tomcat5.0 不能安装在一个包含中文字符(或者*也许*非标准 ASCII 码字符)的文件夹里;
 否则,注册为服务后,不能启动。
 原因未知。

 但是,通过命令行执行批处理文件:startup.bat 是可以正常启动的。

2、如果把 Tomcat5.0 安装为服务程序,
 则可以不用安装 JDK ,只安装 JRE 就可以将 Tomcat5.0 注册为服务程序,并且正常启动;
 但是通过命令行方式无法启动 Tomcat5.0 。

 但是,必须在 %TOMCAT_HOME%\common\lib 下包含 Tomcat5.0 自带的 tools.jar ,
 才可以不安装 JDK 而能正常编译 JSP 。

 结论:对于 Tomcat5.0 服务程序来说,JDK 只是用于编译 JSP,而不是用于注册、运行 Tomcat5.0 和 Web 程序。

3、JDK 和 JRE 都可以通过拷贝的方式安装,

 可以通过在 Windows 系统环境中设置 JAVA_HOME
 或者在
  Tomcat5.0 的启动批处理文件 startup.bat
 和
  Tomcat5.0 的服务注册批处理文件 service 中

 设置 JAVA_HOME 指向 JDK 的安装路径,注意,必须在 JDK 的安装路径中包含 jre (建议小写)目录。

4、Tomcat5.0 的安装版本自带将自己安装为服务程序的功能。

5、Windows 系统必须为2K以上。

6、%TOMCAT_HOME%\bin 目录下的任何批处理文件都和将 Tomcat5.0 设置为服务程序无关,
 只有 tomcat5.exe 这个程序用于将 Tomcat5.0 设置为服务程序,并且运行服务。

7、Tomcat5.0 服务程序默认将日志输出到 %TOMCAT_HOME%\logs 目录下,可以在 service.bat 文件中更改。

2006年03月26日

        天热口渴,一进避风塘就要了好几杯各种汽水,一饮而进,杯子小还全是冰,没有什么真内容,一下就喝调好几杯,每个杯子都剩下好多冰。突然一个很环保的想法诞生了,服务员收走这些杯子以后,会不会继续用这些冰块放在下一个人的杯子里,对于18元一位的价格,这种做法是完全可能的,即节水又节电,还省事,完全合乎JS的逻辑。

        看来我还是有JS的潜力。嗯,佩服!