Archive for May, 2007

我的个人站长路之二:牛刀小试,最高月入2万

Thursday, May 3rd, 2007

版权申明:你可以任意转载此文,但必须保持文章的完整性,并且标明此文的出处,谢谢!
作者序:做个人网站,很多机遇,也有很多无聊。有的人可能颗粒无收、血本无归;但有的人可能一本万利、日进千斗。
写这些东西算是记个流水帐吧,对自己是个总结和回忆,对有些开始做个人网站的人希望能起到借鉴作用。写的时候采用发散思维的方式,想到哪,写到哪,见谅。原因是个人网站牵涉到面太广了,所以我尽可能的把重要的东西点出来。

阶段二、做中文下载搜索网站:www.soudown.com(2004年下半年)。主要提供MP3、电影、MTV、 软件、游戏、Flash、书籍等文件提供搜索。这个网站技术难度还是有些的,从头到尾,我自己开发了爬虫,全文检索,网页前端等。全部都是一个人,使用java开发的。前前后后光开发、调试、就花了2个多月!期间还开发了很多数据整理的小工具。 这个网站壮大非常快,经过大概3个月左右,alexa排名就挤进1000万,接下来一般在3000-6000徘徊,最高日排名达到过2000多,日IP 30万左右。流量增加得这么快,要得益于我的SEO。光是搜索引擎每天就给我带来每天10万以上的IP。
这个网站虽然流量大了,但是问题出来了:1、一台1U的服务器根本没有办法承受这么大的搜索量,tomcat经常死掉,有时候拖得APACHE也死掉。2、我的IDC给我网络流量报告说1秒最大流量达到12M,把整个网段的其他服务器都拖慢了,只好限制我的流量。
3、收益和网站发展问题。一开始我的思路是根本不放任何广告,但是迫于个人财务方面压力(正好这时候我买了房子,首付后存折只有几千快的存款,还贷款了几十万)。这时候我开始投放广告了,想利用网站本事的收益来增加服务器和带宽。一开始是投放异趣的广告,接下来是套宝,Adsense,捷报电影推广,百度搜索联盟等。一开始收益全部加起来大概几千快一个月吧(扣掉个人所得税),最多的时候大概税后2万多人民币。
4、后来虽然收益是多了,可是广告太多,影响用户体验,慢慢流失用户。当我赚了钱准备开始新的投入时,Google搜索封杀了我的网站,使得流量大减。我不得不重新评估这个网站是否有继续发展的价值,最后又是决定淡出这个网站。当网站流量下降到PV 5000后,我就关闭了。
这个网站域名最后居然忘记续费,被人家抢注,还些乱七八糟的广告。真是郁闷:(

经验教训总结:
1、用户体验很重要,不要把用户淹没在无边的广告中。现在中国很多个人网站为了盈利不惜一切手段,能放广告的地方都放了,广告比网站内容还多。这种情况我还只有在国内发现。简单的说,如果你想留下用户,少放广告!
2、国内的广告商很黑!一是很多广告商都扣点,我没搞明白他们为什么要扣点。二是个人所得税问题,多的时候他们一个月扣了我几千快个人说得税,但我从来没有看到一张个人所得税的完税发票!这还不算,有的广告商不管你收入多少,都扣20%的所得税。这和所得税法规是相背的。网站收入可以算是个人劳动所得,个人劳动所得的起征点是800(3年以前是这样,现在我不知道了)。
3、网站要有明确的发展目标,不能走到哪里算哪里,网站发展是动态的,很多情况要考虑周全:包括资金,人员的投入、预期的收入。当时要是积极联系一些风险投资商,获得投资就好了。毕竟2004年做下载搜索的人不多,现在这方面的网站不少了,而且发展也不错。
4、经验,进一步在实践中总结了很多SEO经验,认识了当时国内很多SEO同行,和他们在一起非常快乐。当时排名的水平可以说达到了炉火纯青的地步:搜索结果千万级的关键词都可以做到首页,甚至no.1,成功的词有:mp3下载,MTV下载,电影下载等。同时对搜索引擎的构架也有个比较深刻的认识。

我的个人站长路之一:初生牛犊、知识积累的路上

Wednesday, May 2nd, 2007

版权申明:你可以任意转载此文,但必须保持文章的完整性,并且标明此文的出处,谢谢!
作者序:做个人网站,很多机遇,也有很多无聊。有的人可能颗粒无收、血本无归;但有的人可能一本万利、日进千斗。
写这些东西算是记个流水帐吧,对自己是个总结和回忆,对有些开始做个人网站的人希望能起到借鉴作用。写的时候采用发散思维的方式,想到哪,写到哪,见谅。原因是个人网站牵涉到面太广了,所以我尽可能的把重要的东西点出来。

我的个人站长路之一:初生牛犊、知识积累的路上

缘起:毕业工作后,一直从事软件开发、业余时间发发文章、写写书籍、讲讲技术课程,过得也瞒充实的。其实这些都是我对未来职业规划的一些尝试,当然也可以积累一些经验、知识。
一个偶然的机会,让我对互联网有了兴趣。好在以前做软件开发都是B/S结构,而且使用Java、J2EE、JSP等技术,熟悉了这些技术,做网站简直就是轻车熟路。
大概在2004年初,我买了台1U的服务器,服务器加托管一共花了进2万人民币。当时根本没有考虑到盈利等问题,现在回想起来真是有点冲动。

阶段一、一开始做了一个英文电子书共享的网站,这个网站虽然没有给我带来很多收入,但我学习了不少知识。

为了推广网站,我也想过很多办法,其中最有效的是搜索引擎优化。当时,国内玩SEO的人可以说凤毛麟角,但是国外已经相对比较普及。期间,我经常去国外的一些SEO论坛交流,比如http://www.webmasterworld.com/ 的SEO版,www.seochat.com等,这些论坛人气很旺,交流的信息都很中肯。忘了说了,这个电子书共享网站的主要收入是靠会员捐款,大概2个月后就开始有点稳定的收入,大概一天平均有10美元吧。但存在一个致命的问题:版权。开始做这个网站时我没有意识到,后来我觉得这种网站不是长久之计。 所以这个网站运营3个月后,我就慢慢淡出,最后决定彻底关闭。
关于这个网站,我还有个问题要说,就是paypal的问题,paypal收款很容易,可是撤款对于中国人来说简直就是难于上青天。由于当时我不太懂,注册paypal时随便写了个名字,做了一段时间我才发现根本没有办法撤款。所以这个钱我到现在都没有办法拿回来。paypal现在虽然可以直接提现到银行卡里,但使用仍然有很大的风险,稍微不小心,你帐号就limited了!我有很多朋友都有血的教训,但这也不能全怪payapl,因为前几年太多的中国人在ebay上骗钱,通过paypal收款。他们只收款不发货,有的一天就骗1万多美元。有的帐号中有几十万美元,也拿不回来。

经验教训总结:1、个人网站内容一定要健康,合法。否则不可能有长久发展。如果不健康的网站,网站发展越大,你就越提心吊胆。
2、从国外做项目撤资困难,稍有不慎,可能血本无归。
3、经验,真的学到SEO很多知识,使得我对网站推广信心大增!

Building Scriptless JSP Applications with JSP2.0 Expression Language

Wednesday, May 2nd, 2007

版权申明:你可以任意转载此文,但必须保持文章的完整性,并且标明此文的出处,谢谢!
作者序:这是我4年前练手写的一篇英文技术文章,几乎没有公开过,出来献丑了。

Building Scriptless JSP Applications with JSP2.0 Expression Language

Level: Intermediate

Summary:

The Primary feature of JSP technology version 2.0 is its support for an expression languag, the expression language can now be used in JSP page instead of scriptlet expressions. In this article, first introduce some important concept about JSP2.0 Expression Language (EL), then demonstrate how to use EL to build a scriptless sample JSP application.
Expression Language Introduction

The JavaServer Pages Standard Tag Library (JSTL) expression language is now integrated into JSP technology and has been upgraded to support functions. The expression language can now be used in JSP page instead of scriptlet expressions. By use of Expression Language, Web designers produce scriptless JSP pages that don’t contain any Java code.

An expression language makes it possible to easily access application data stored in JavaBeans components or JSP implicit objects.

For example, in JSP1.2, you can use the following code to access a JavaBeans component:

Listing 1. access JavaBeans components with JSP1.2 or earlier

<jsp:useBean id=”user” class=”com.hellking.UserBean” scope=”page”/>

<%

out.println(user);

out.println(user.getUserName());

%>

In JSP2.0, you can access the property and variable by using EL through the following way:

Listing 2: access JavaBeans components by EL with JSP2.0

<jsp:useBean id=”user” class=”com.hellking.UserBean” scope=”page”/>

${user}<br>

${user.userName}

In listing2, we use “${user}” to access the JavaBean component, and use “${user.userName}” to access a nested property, and we can use “${user.userName.firstName}” to access more complex nested property.

The JSP expression evaluator is responsible for handling EL expressions, which may include literals and are enclosed by the ${ } characters. For example:

<c:if test=”${user.age < 30}” >

</c:if>

We can use the Expression Language to set tag’s property, for example:

Listing 3 set tag’s property

<c:set target=”${user}” property=”userName”>sdf234sdfd</c:set>

<c:set var=”foo” value=”the user is ${user.userName} and the password is ${user.password}”/>

The JSP container evaluates a variable that appears in an expression by looking up its value according to the behavior of PageContext.findAttribute(String). For example, when evaluating the expression ${user}, the container will look for user in the page, request, session, and application scopes and will return its value. If both the page and session has the attribute “user”, it will return the attribute of the page. If “user” is not found in any scope , null is returned.

The JSP expression language defines a set of implicit objects (Don’t confuse these with the JSP implicit objects), with the implicit objects, you can access variable in a very easy way. For example, in JSP1.2 or earlier, you use following code to access implicit objects and their values:

Listing 4 access implicit objects with JSP1.2 or earlier

<%

session.setAttribute(“user”,”hellking”);

out.println(session.getAttribute(“user”));

out.println(request.getParameter(“password”));

%>

And you may use the following code in JSP2.0:

Listing 5 access implicit objects with JSP2.0

<c:set var=”user” value=”hellking” scope=”session”/> <!–set a property in session –>

${sessionScope.user}<br> <!– get a property in session –>

${param.password}<br> <!– equal to request.getParameter(“password”) –>

You can see, Expression language provide a map between JSP implicit objects and their method(property).

You can access the JSP page context objects, page/request/session/application attributes (also known as JSP variables), JavaBean properties, collection elements, request parameters, initialization parameters, cookies, and HTTP headers.

With JSP 1.2, the expression language is available only to JSTL-based applications and tag libraries. JSP 2.0 makes the EL available to all JSP applications and all tag libraries (including the old taglibs designed for JSP 1.x). JSP 2.0 also simplifies tag library development, as you’ll see later in this article.

For more information about implicit objects map, see The Java Web Services Tutorial, http://java.sun.com/webservices/docs/1.2/tutorial/doc/JSPIntro7.html#wp71043.

NOTE:

JSP2.0 Expression Language is somewhat different from JSLT1.0 Expression Language. For Example, in JSTL1.0, use the following to output the variable’s value to client:

<c:out value=”${test}”/>

and in JSP2.0 EL, just use the following code:

${test}

Set up envirmonent

1. Download Apache Tomcat 5.0 and setup it, see Resource.

2. Create a web application in %Tomcat_Home%\webapps directory, the web application name is “el”.

3. In the “el” application directory, create a sub directory WEB-INF; and then in WEB-INF directory, create a web application descriptor file: web.xml. Copy the following descriptor to web.xml file.

Listing 6 new web.xml descriptor

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<web-app xmlns=”http://java.sun.com/xml/ns/j2ee”

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd”

version=”2.4″>

<display-name>jstl_el</display-name>

<description>

a demo EL application

</description>

<welcome-file-list>

<welcome-file>viewUser.jsp</welcome-file>

<welcome-file>index.html</welcome-file>

</welcome-file-list>

</web-app>

NOTE: JSP2.0 descriptor is defined by w3c schema, and JSP1.x descriptor is defined by DTD. So I recommend you use the new descriptor, or if you use old descriptor, you JSP file may include:

<%@ page isELIgnored =”false” %>

4. In the WEB-INF directory, create a sub directory, the name is lib. Copy jstl.jar and standard.jar form %Tomcat_Home%\webapps\jsp-examples\WEB-INF\lib to the lib directory.

5. Test configuration. In the el directory, create a JSP whose name is el.jsp, and then copy the following code to the el.jsp file.

Listing 7 Test EL configuration

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>

<html>

<head>

<title>test jstl configuration</title>

</head>

<body bgcolor=”#FFFFFF”>

<hr>

<c:set var=”test” value=”test_Value”/>

<hr>

the value of test is:

${test}</body>

</html>

Startup Tomcat, view the following URL from the browser:

http://127.0.0.1:8080/el/el.jsp

If the output is:

the value of test is: test_Value

Congratulation! the first EL application is run!

Build a Sample application

Now we discuss how to build a JSP application with JSP2.0 EL.

The application is a simple user register and manage program. The following is user register interface.

Figure 1 user register interface(userRegister.jsp)

And you can delete registered user in the following interface.

Figure2 view and delete registered user(viewUser.jsp)

In the database, use the following script to create a table:

use test;

create table UserInfo(id varchar(20) not null,userName varchar(30),password varchar(20),age int,constraint pk_UserInfo primary key (id));

And then you may copy the class file of the database server’s JDBC driver to the %Tomcat_Home%\common\lib directory.
jstl.inc

jstl.inc file is a public file included by other JSP.

Listing 8 jstl.inc

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ page language="java" errorPage="error.jsp" %>

<sql:setDataSource

var="jspdev"

driver="org.gjt.mm.mysql.Driver"

url="jdbc:mysql:///test"

user="root"

password=""

scope="session"

/>

You may modify the content of the <sql:setDataSource> tag according to the database settings.

NOTE

The uri of JSP2.0 tag is

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

but by default, the uri of JSTL1.0 tag is:

<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

Don’t be confused.

userRegister.jsp

userRegister.jsp contain a HTML form, which used to submit user’s registration information. If the submitted registration information is invaluable, the error message and original parameter’s value is returned.

Listing 9 userRegister.jsp

<%@ include file="jstl.inc"%>

note:${param.message}<br></font>

User Register:<br><hr>

:::please input your register info and submit:::

<form method="get" action="register_do.jsp" name="user" onsubmit="return validate(user.age)">

<table align="center" bgcolor="#008800" border="0" cellspacing="2" cellpadding="5">

<tr bgcolor="#cccccc"><td align=right>login id:<input name="id" type="text" value="${param.id}" ></td></tr>

<tr bgcolor="#cccccc"><td align=right>true name:<input name="userName" type="text" value="${param.userName}"></td></tr>

<tr bgcolor="#cccccc"><td align=right>password:<input name="password" type="password" value="${param.password}"></td></tr>

<tr bgcolor="#cccccc"><td align=right>your age:<input name="age" type="text" value="${param.age}" ></td></tr>

<tr bgcolor="#cccccc"><td ><input type=submit value="submit"></td></tr>

</table>

</form>

<c:import url="tail.html"/>


register_do.jsp

In the register_do.jsp, first it validate the form’s parameter, if the parameter is invaluable, redirect back to the registration page; if the parameter is validly, execute the <sql:update> tag and save the data to database.

Listing 10 register_do.jsp

<%@ include file="jstl.inc"%>

<c:choose>

<c:when test="${empty param.id or empty param.userName or empty param.password}">

<c:set var="nextPage" value="userRegister.jsp"/>

<c:set var="message" value="column id. name .password can't be null!" scope="page"/>

</c:when>

<c:when test="${empty param.age or param.age gt 100 or param.age lt 0}">

<c:set var="nextPage" value="userRegister.jsp"/>

<c:set var="message"

value="column age can not be null, and age must be a integer between 0 and 100 !'"/>

</c:when>

<c:otherwise>

<sql:update var="user"

dataSource="${jspdev}"

sql="insert into UserInfo

values('${param.id}','${param.userName}','${param.password}','${param.age}')"/>

<c:set var="nextPage" value="viewUser.jsp"/>

<c:set var="message" value="${param.id}"/>

</c:otherwise>

</c:choose>

<c:redirect url="${nextPage}">

<c:param name="message" value="${message}"/>

<c:param name="userName" value="${param.userName}"/>

<c:param name="id" value="${param.id}"/>

<c:param name="age" value="${param.age}"/>

<c:param name="password" value="${param.password}"/>

</c:redirect>

See the following EL:

${empty param.id or empty param.userName or empty param.password}

is equal to:

<%

if(request.getParameter("id").equals(null)||request.getParameter("id").equals(null)||request.getParameter("id").equals(null))

%>

“empty” and “or” are EL operator, “empty param.id” means no request parameter “id” or the request parameter “id” has a null value. The following EL:

${empty param.age or param.age gt 100 or param.age lt 0}

is equal to:

<%

if(request.getParameter("age").equals(null)||Integer.parseInt(request.getParameter("age"))<0 ||Integer.parseInt(request.getParameter("age"))>100)

%>

“gt” and “lt” is EL operator, ”gt” means the mathematic operator ”>”, ”lt” means the mathematic operator ”<”.
viewUser.jsp

viewUser.jsp is used to view the registered user’s information.

Listing 11 viewUser.jsp

<%@ include file="jstl.inc"%>

<sql:query var="query" dataSource="${jspdev}">

select * from userinfo

</sql:query>

<br><br><br>

:::::::::the follow is all user in the system:::::::::<br>

<table align="center" bgcolor="#008800" border="0" cellspacing="2" cellpadding="5">

<tr bgcolor="#cccccc">

<td>id</td>

<td>name</td>

<td>age</td>

<td>delete</td>

</tr>

<c:forEach var="row" items="${query.rows}">

<tr bgcolor="#FFFF88">

<td> ${row.id}</td>

<td> ${row.userName}</td>

<td> ${row.age}</td>

<td><a href="deleteUser_do.jsp?id=${row.id}"/>delete</a></td>

</tr>

</c:forEach>



Unlike the JDBC programme, you can use ${row.id} EL to access the ResultSet Object. As you can see, ${row.id} is equal to the following scriptlet:

<% out.println(resultSet.getString(“id”);%>

Because a JSP function is used in deleteUser_do.jsp, so let’s see something about JSP function.
Use function in JSP2.0

JSP2.0 EL lets you call a Java class’s public static method using the following syntax:

${prefix:methodName(param1, param2, …)}

The JSP function must be declared in a tag library descriptor (TLD):

<function>

<name>methodName</name>

<function-class>className</function-class>

<function-signature>

returnType methodName(param1Type, param2Type, …)

</function-signature>

</function>

The Java class doesn’t have to implement any special interface. The only requirement is to make the Java method public and static.

The following is the function’s class used in the demo application.

Listing 12 StringUtil.java

package com.hellking;

public class StringUtil

{

public static String trim(String s1)

{

return s1.trim();

}

}

As mentioned earlier, the JSP function must be declared in a tag library descriptor. The functions.tld file defines some version number, the library’s URI, the function’s name, the name of the class containing the static method, and the method’s signature. The URI doesn’t have to point to an existing Web resource, but it must be unique. You may not use the same URI for two different tag libraries.

Here is the functions.tld file’s content:

Listing 13 functions.tld

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<taglib xmlns=”http://java.sun.com/xml/ns/j2ee”

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd”

version=”2.0″>

<tlib-version>1.0</tlib-version>

<jsp-version>1.2</jsp-version>

<short-name>function</short-name>

<uri>http://hellking.com/function</uri>

<display-name>JSTL sql RT</display-name>

<description>my function</description>

<function>

<name>trim</name>

<function-class>com.hellking.StringUtil</function-class>

<function-signature>java.lang.String trim(java.lang.String)</function-signature>

</function>

</taglib>

The functions.tld file must be placed into the Web application’s /WEB-INF directory. The same directory also contains the web.xml application descriptor, which declares the library within a <taglib> element. Add the following descriptor to the web.xml descriptor file.

Listing 14

<taglib>

<taglib-uri>http://hellking.com/function</taglib-uri>

<taglib-location>/WEB-INF/functions.tld</taglib-location>

</taglib>

Now let’s see the usage of the JSP function.

Listing 11 deleteUser_do.jsp

<%@ taglib prefix=”myfun” uri=”http://hellking.com/function”%>

<%@ include file=”jstl.inc”%>

<sql:update var=”user”

dataSource=”${jspdev}”

sql=”delete from UserInfo where id=’${myfun:trim(param.id)}’”/>

<c:redirect url=”viewUser.jsp”/>

Before calling the trim () function, the deleteUser_do.jsp page must specify the function’s prefix and the library’s Uniform Resource Identifier (URI):

<%@ taglib prefix=”myfun” uri=”http://hellking.com/function”%>

And then we can use the function as the following way:

${myfun:trim(param.id)}

“myfun” is the prefix of the tag, “trim()” is name of the function defined in the tag library’s descriptor.

Resource:

Down the sample code here .

Download Tomcat 5 to run the JSP 2.0 examples:

http://jakarta.apache.org/builds/jakarta-tomcat/release

The Java Web Services Tutorial:

http://java.sun.com/webservices/docs/1.2/tutorial/doc/index.html

The JSP homepage: http://java.sun.com/products/jsp

The JSTL homepage:

http://java.sun.com/products/jsp/jstl

The JSP 2.0 specification:

http://jcp.org/aboutJava/communityprocess/first/jsr152/index2.html

The J2EE 1.4 Tutorial has a few chapters about JSP 2.0:

http://java.sun.com/j2ee/1.4/docs/tutorial

Call JavaBean methods from JSP 2.0 pages:

http://www.javaworld.com/javaworld/jw-05-2003/jw-0523-calltag.html

Apache Tomcat 5 supports JSP 2.0:

http://jakarta.apache.org/tomcat

A JSTL primer, Part 1: The expression language:

http://www-106.ibm.com/developerworks/java/library/j-jstl0211.html

About the author

Ya qiang Chen, a professional J2EE programmer, he has three years J2EE experience. He is interested in J2EE and Web Services technology. Except successful J2EE project, he also has written some books and articles about J2EE/Web Services program. Contact Ya qiang Chen at cyqcims@mail.tsinghua.edu.cn.

关于我,打油诗 ^_^

Wednesday, May 2nd, 2007

版权申明:你可以任意转载此文,但必须保持文章的完整性,并且标明此文的出处,谢谢!
作者序:文章虽短,但总结了我近15年的人生酸甜苦辣。写在这里,自娱自乐吧。

人生虽短,道路坎坷。
中专失败、辍学无奈;
赚钱打工、高考成功;
主修民航、兼修计算机;
得过表扬、受过处分;
学习网络、考过思科;
工作转行、道路漫长;
先搞编程、后是Design;
发表文章、撰写书籍;
前途渺茫、投身互联网;
命运改变、在此一念;
单枪匹马、奋战三年;
日进千斗、好运时有;
车房虽有、前途担忧;
资金不缺、项目难得;
寻找朋友、创业长久。

出版书籍

Wednesday, May 2nd, 2007

以前写过的几本技术书籍,水平有限,拿出来献丑了。

  • JSP 应用开发详解(第二版)
  • 【出 版 社】 电子工业出版社
    【书 号】 7-5053-9419-3
    【开 本】 16开
    【页 码】 592
    【出版日期】 2004年1月

  • J2EE应用开发详解

  • I S B N: 7121004305
    页 数: 581
    开 本: 小16开
    封面形式: 简裝本
    出 版 社: 电子工业出版社
    出版日期: 2004-10-1

  • J2EE企业级应用开发
  • 丛编题名: 开发专家之Sun one
    ISBN号: 7-5053-8943-2
    出版发行项: 北京-电子工业出版社 2003
    载体信息: ⅩⅢ, 632页 26cm CNY59.00 (附光盘) 1张光盘