声明:原创作品,出自 “深蓝的blog” 博客。欢迎转载。转载时请务必注明出处,否则追究版权法律责任。
深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/39780805
枯燥的知识点介绍是漫天飞舞。我们最好还是从中筛选出部分细节,带着问题来学习Oracle体系知识,这样或许印象会更深刻吧。接下来的一段日子里,本人为了通过ocp考试,将会通过这样的形式,開始oracle体系、备份、调优等一系列的学习梳理与练习。下面即是一个自我的总结。也作为网络上的简单分享。
基础知识,假设也能帮助到刚開始学习的人,欣慰不已。
【不耻下问】
问题1:oracle网络是没有负载的,绘制简单的网络拓扑结构?
数据库由PGA、SGA、相关文件构成,当实用户发出请求时,会通过监听建立连接。生成server process进程。建立网络连接后,监听就不再起作用,一切交互都仅仅会由server process来完毕。
绘制简单拓扑结构。例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmd5YW5sb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">
问题2:简述监听与数据库间的关系?
监听:对于oracle来说是一个独立的模块。
既能够先启动oracle。再启动监听。也能够先启动监听,再启动oracle。
问题3:监听和数据库间是否存在长连接?
监听和数据库之间是不存在长连接,这个要明白,仅仅是体现出来的效果是:须要连接时监听能够找到数据库的位置。相同须要连接时数据库也能够找到监听的位置。给人的直观感觉是两者间似乎是存在着长连接的关系,但这并不存在。
问题4:简述client和实例是怎样通过监听建立连接的?
由于监听知道数据库在详细的位置,便能够依据请求而建立连接。当用户连接监听时,由于监听是知道数据库的位置的,所以监听就会把用户的连接请求转发给实例(即数据库)。实例会专门为连接启动一个server process。同一时候会把service process的地址告诉监听,监听会把server process地址告诉给client,client会直接发起对server process的连接请求,这时候client和oracle的实例正式建立起连接。
然后client会把username和password交由server process,而server process会将username和password传递给数据库来进行验证。
验证成功后,就标志着这个连接正式建立了。
此后,client和数据库之间的会话全交由server process来完毕。而监听已经完毕了它的使命,不会再起作用了。更明白一点。监听仅仅是在建立连接时才会起作用,监听是没有负载的,这也就与第1题中说的网络没有负载相应上了。
问题5:监听什么时候最easy出问题?
短时间内发起大量的请求。当有大量连接请求时。比方说短时间内出现上百个连接请求的时候,会超过监听的承载负荷,这段时间内一般是会出现延迟现象。这时候最直观的反应就是,连接数据库时会发现响应时间变长了。
问题6:建立监听后。怎样立马完毕动态注冊?
无配置启动监听后。须要60秒才干注冊。
假设想要立马注冊,须要在sqlplus下手工运行语句,例如以下:
SQL> alter system register;
System altered.
[oracle@hyl ~]$ lsnrctl status
--查询监听状态,你会发现已经完毕了注冊工作
问题7:监听涉及到的文件有哪些?
tnsnames.ora(client文件)、listener.ora(server端监听文件)、sqlnet.ora(这是个可选文件)。
问题8:配置监听时怎样启动图形化?
在主机端或者远程使用X-manager、VNC等软件,能够调出oracle图形化界面,启动图形化之前,须要操作例如以下指令:
[root@hyldb ~]# xhost +
access control disabled, clients can connect from any host
[root@hyldb ~]# export DISPLAY=192.168.1.104:0.0
--把图形化界面引入到本地,这里的IP地址是用于远程调取图形化界的机器IP地址
[root@hyldb ~]# su - oracle
[oracle@hyldb ~]$ netca
例如以下出现配置监听图形化
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmd5YW5sb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">
接下来依照步骤逐步完毕就可以。
完毕后,会自己主动生成一个listener.ora文件。
问题9:监听文件的路径是什么?
监听文件一般存在于oracle根文件夹下。能够通过例如以下路径找到:
[root@hyldb ~]# su - oracle
[oracle@hyldb ~]$ cd $ORACLE_HOME
[oracle@hyldb db_1]$ ls
apex deinstall jdev opmn slax
assistants demo jdk oracore sqldeveloper
bin diagnostics jlib oraInst.loc sqlj
ccr dv ldap ord sqlplus
cdata emcli lib oui srvm
cfgtoollogs EMStage log owb startup.log
clone has md owm suptools
config hs mesg perl sysman
crs ide mgw plsql timingframework
csmig install
network precomp ucp
css instantclient nls racg uix
ctx inventory oc4j rdbms usm
cv j2ee odbc relnotes utl
dbs javavm olap root.sh wwg
dc_ocm jdbc OPatch scheduler xdk
[oracle@hyldb db_1]$ cd network
[oracle@hyldb network]$ ls
admin doc install jlib lib log mesg tools trace
[oracle@hyldb network]$ cd admin
[oracle@hyldb admin]$ ls
listener1410017PM0213.bak samples tnsnames1410017PM0719.bak
listener1410017PM0233.bak shrept.lst tnsnames.ora
listener1410017PM0719.bak tnsnames1410017PM0213.bak
listener.ora tnsnames1410017PM0233.bak
[oracle@hyldb admin]$ pwd
--使用pwd命令查看到全路径
/u01/app/oracle/product/11.2.0/db_1/network/admin
问题10:监听文件里须要注意的内容有哪些?
打开listener.ora文件,例如以下操作
[oracle@hyldb admin]$ vi listener.ora
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hyldb)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
一般仅仅须要注意如上几段信息就可以,注意HOST的值为server主机的主机名。一般会设置为IP地址,例如以下格式:
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.123)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
问题11:怎样启动、关闭、查看监听?
[oracle@hyldb admin]$ lsnrctl start
--启动监听
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 00:42:49
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Starting /u01/app/oracle/product/11.2.0/db_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 11.2.0.4.0 - Production
System parameter file is /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora
Log messages written to /u01/app/oracle/diag/tnslsnr/hyldb/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=hyldb)(PORT=1521)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hyldb)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.4.0 - Production
Start Date 04-OCT-2014 00:42:49
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/hyldb/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=hyldb)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
The listener supports no services
The command completed successfully
[oracle@hyldb admin]$ lsnrctl status
--查看监听
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 00:43:18
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hyldb)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.4.0 - Production
Start Date 04-OCT-2014 00:42:49
Uptime 0 days 0 hr. 0 min. 28 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/hyldb/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=hyldb)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "hyl" has 1 instance(s).
Instance "hyl", status READY, has 1 handler(s) for this service...
Service "hylXDB" has 1 instance(s).
Instance "hyl", status READY, has 1 handler(s) for this service...
The command completed successfully
[oracle@hyldb admin]$ lsnrctl stop
--停止监听
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 00:42:35
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hyldb)(PORT=1521)))
The command completed successfully
[oracle@hyldb admin]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 00:42:45
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hyldb)(PORT=1521)))
TNS-12541: TNS:no listener
TNS-12560: TNS:protocol adapter error
TNS-00511: No listener
Linux Error: 111: Connection refused
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
TNS-12541: TNS:no listener
TNS-12560: TNS:protocol adapter error
TNS-00511: No listener
Linux Error: 2: No such file or directory
问题11:怎样实现启动监听后。马上完毕注冊?
启动监听后一般要过60秒才会完毕注冊,但能够在sqlplus中手工运行命令,使其马上完毕注冊,操作例如以下:
SQL> alter system register;
此命令会触发pmon进程去将实例名字动态注冊到监听中去。
问题12:怎样生成tnsnames.ora文件?
參考图形化配置的方法,能够使用netca命令。调出图形化配置选项,例如以下选择第三项即为配置tnsnames.ora文件。配置好后会自己主动生成一个tnsnames.ora文件。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmd5YW5sb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">
选择进行測试一下,例如以下:
以下这个服务名能够随意取。与前面的数据库服务名是两个概念。请注意。
点击完毕选项。完毕tnsnames.ora文件的创建。例如以下图所看到的:
问题13:在加入tnsnames.ora时会要求填写数据库服务名,这个名字应该根据什么进行填写?
在sqlplus中使用例如以下命令,就可以查看到服务名。
SQL> show parameter service NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string hyl
问题14:怎样查看1521port的占用情况?
[root@hyldb ~]# netstat -tulnp|grep 1521
tcp 0 0 192.168.1.123:1521 0.0.0.0:* LISTEN 3473/tnslsnr
一般数据库server上本身会有不止一块网卡,通过命令能够查看到使用的哪一个网卡。
问题15:怎样查看到tnsnames.ora文件及应该注意什么?
SQL> show parameter service NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ service_names string hyl
注意这里上面的“HYL”是能够随意取得,而以下的SERVICE_NAME = hyl。这里的SERVICE_NAME必需要和数据库服务名全然一样。
问题16:client连接数据库书写格式是如何及为何这样书写?
一般书写格式为username/password@servicename。
之所以这样的格式书写。是由于当遇到@这个符号时,oracle会自己主动到tnsnames.ora文件里解析@后跟的字符串。通过tnsnames文件解析字符串,tnsnames.ora文件里包括IP地址、port号、数据库服务名。也就是说,当client进行sqlplus书写格式登陆数据库时,oracle会依据@字符后的字符串去到tnsnames.ora文件里相应的字符串解析出IP地址、port号、数据库服务名的信息。
问题17:当client无法连接oracle数据库时,怎样进行排错?
(1)、查看clienttnsnames.ora文件设置是否正确。检查service_name(參考问题13)是否与数据库端同样。
(2)、查看server段IP地址、port号(參考问题14)是否正确。
(3)、client使用tnsping命令ping服务名。查看情况,例如以下代表能够解析成功:
[oracle@hyldb admin]$ tnsping beijing_daotian
TNS Ping Utility for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 01:34:07
Copyright (c) 1997, 2013, Oracle. All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.123)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = hyl)))
OK (10 msec)
这里要注意。tns能够ping成功,也可能存在其他问题致使无法连接oracle。如你使用了一个没有注冊到监听的service_name,tnsping能够完毕,但此情况是无法连接数据库的。
问题18:在oracle网络中几个文件涉及到了service_name这个概念,之间是如何的关系?
tnsnames.ora中service_name和listener.ora(监听文件)中service_name是相应的,应该与oracle的service_name相一致。当client发出请求时。会依据tnsnames.ora中的service_name与数据库server端监听文件里的service_name进行比对。仅仅有一致时才会完毕解析工作,client同监听建立起连接。
这样监听才会把连接转移到数据库实例上。而实现client与oracle建立连接。
问题19:静态注冊、动态注冊的差别?
静态注冊须要手工在listener.ora文件里加入内容,例如以下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = 数据库服务名)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
(SID_NAME = 数据库实例名)
)
)
注冊后能够查看效果,按例如以下操作:
[oracle@hyldb admin]$ lsnrctl stop
[oracle@hyldb admin]$ lsnrctl start
[oracle@hyldb admin]$ lsnrctl status
--查看到当中标识有UNKNOWN代表静态注冊的监听
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 04-OCT-2014 12:28:47
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hyldb)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.4.0 - Production
Start Date 04-OCT-2014 12:28:16
Uptime 0 days 0 hr. 0 min. 30 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/hyldb/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=hyldb)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "hyl" has 2 instance(s).
Instance "hyl", status UNKNOWN, has 1 handler(s) for this service...
Instance "hyl", status READY, has 1 handler(s) for this service...
Service "hylXDB" has 1 instance(s).
Instance "hyl", status READY, has 1 handler(s) for this service...
The command completed successfully
动态注冊:
1、注意内容:配置local_litener參数,须要指定监听的host和port。
2、注冊过程:假设监听先启动。实例后启动,实例会完毕动态注冊。假设实例先启动,监听后启动,须要使用SQL>alter system register;完毕注冊;
3、显示状态:假设实例的状态是nomount。监听会显示BLOCKED。假设实例状态是mount或open。监听会显示为READY。
静态注冊:
1、注意内容:要配置对应的SID列表。
2、显示状态:静态注冊,不管是否启动。都会显示为UNKNOWN状态。
两者的优势分别在于动态注冊方便、静态注冊稳定。
问题20:使用静态注冊的原因是什么?
静态注冊为了解决oracle动态注冊不稳定的情况。同一时候也为解决针对于老版本号oracle(如8i之前)数据库的连接时使用。
问题21:oracle的服务名、数据库名、实例名怎样查看?
參照问题13。我们能够用类似的方法在sqlplus中查看到每一个名字,操作如:
SQL> show parameter name NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cell_offloadgroup_name string
db_file_name_convert string
db_name string hyl
db_unique_name string hyl
global_names boolean FALSE
instance_name string hyl
lock_name_space string
log_file_name_convert string
processor_group_name string
service_names string hyl
由上表能够查看到数据库的服务名(service_name)为hyl,数据库名(db_name)为hyl,实例名(instance_name)为hyl。这里设置为了同一个名称,为了操作方便,但要注意这几个名词所代表的含义并不相同。service_name是能够随意改动的。可是假设你改动了service_name,你相同须要改动监听器、client文件里的service_name,否则将无法完毕监听连接。
相同。这里又想起一点。就是在静态注冊时这个service_name是和GLOBAL_DBNAME相相应的。
问题22:通过连接方式判别client是否通过监听连接?
1、本地连接,不走监听,格式如:
sqlplus scott/tiger
sqlplus / as sysdba
sqlplus ‘/as sysdba’
2、client连接,须要监听
sqlplus scott/tiger@hyl
3、使用监听但无需tnsnames.ora连接方式。由于这样的连接方式中IP地址、port号、实例名均手工填写出来了。例如以下所看到的:
sqlplus scott/tiger@192.168.1.123:1521/hyl
【简而记之】
1. 独立性:监听是单独存在的模块;
2. 连接性:监听仅仅在client建立连接时起作用,不存在负载;
3. 连接假象:监听和数据库间。没有长连接。仅仅是彼此间都知道位置所在,在须要连接时能够及时建立连接;
4. 负荷性:监听是有负荷上限的。连接过多会导致延迟。
5. client连接格式:username/password@service_name
【小试牛刀】
说明:下面题目来源于ocp11g考试大纲
题号:130.
Which two statements are true regarding listeners? (Choose two.)
A.Listeners use only the TCP/IP protocol.
B.Multiple listener processes can run simultaneously on a host.
C.Multiple database instances can be registered with a single listener.
D.The listener-related errors can be traced only at the administrative level.
E.Only one database instance can be registered with a single listener at any time.
Answer: BC
深蓝浅析:
A监听器仅仅是一个TCP/IP协议,理解错误,还能够其他通信如IPC(本地间通信协议,此协议使用在本地连接数据库时,即使没有建立监听,也能够连接到数据库);
B一个主机上能够存在多个监听。正确。
C一个监听能够完毕多个数据库的注冊。正确;
D对于监听错误的分析,不仅是管理层,在用户层上相同可能引起监听错误,此项错误;
E与C矛盾,错误。
题号:131.
Which naming method uses the tnsnames.ora file to store the connect descriptor used by the client while connecting to the database instance from a remote machine?
A.host naming method
B.local naming method
C.external naming method
D.directory naming method
Answer: B
深蓝浅析:
client连接数据库。使用local naming method的方式,官方文档中明白的指出了。由于tnsnames.ora文件是须要在client连接端使用的文件。
题号:132.
The tnsnames.ora file has an entry for the service alias ORCL as follows:
ORCL =
( DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.156.24.216)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl.oracle.com)
)
)
The TNSPING command executes successfully when tested with ORCL, but you are not able to connect to the database instance with the following command:
SQL> CONNECT scott/tiger@orcl
What could be the reason for this?
A.The listener is not running on the database node.
B.The TNS_ADMIN environmental variable is set to a wrong value.
C.The orcl.oracle.com database service is not registered with the listener.
D.The DEFAULT_DOMAIN parameter is set to a wrong value in the sqlnet.ora file.
Answer: C
深蓝浅析:
tnsping通代表对tnsnames.ora的解析是成功的。但假设tnsnames.ora中的service_name没有注冊到listener.ora中去。仍然是不能连接数据库的。
题号:133.
Your database is open and the LISTENER listener is running. The new DBA of the system stops the listener by using the command:LSNRCTL> STOP
What happens to the sessions that are presently connected to the database instance?
A.The sessions are able to perform only queries.
B.The sessions are not affected and continue to function normally.
C.The sessions are terminated and the active transactions are rolled back.
D.The sessions are not allowed to perform any operations till the listener is started.
Answer: B
深蓝浅析:
监听仅仅有在建立连接时才起作用,连接建立后。监听就完毕了使命,之后的任务都交给了server process了。能够參看问题4。
题号:134.
View the Exhibit and examine the output.
Which two statements are true regarding the LISTENER2 listener? (Choose two.)
A.The ORCL instance is registered dynamically with the listener.
B.The ORCL instance is registered statically in the listener.ora file.
C.The number of current client connections handled by the service handler is two.
D.The total number of client connections handled so far by the service handler is two.
Answer: BD
深蓝浅析:
通过UNKNOWN能够知道这是静态注冊,參考问题19。因此选B。通过established为2能够知道,到眼下为止。建立成功过两个连接。因此选D。
题号:135.
In which situation would you use static database registration for a listener?
A.when multiple databases are to be registered with the listener
B.when DBAs need to connect remotely to start up the database instance
C.when users need to connect the database instance using the host naming method
D.when the database instance that is to be registered with the listener is configured in shared server mode
Answer: B
深蓝浅析:
为了实现远程启动数据库实例,此时须要通过静态数据库注冊来完毕连接数据库。因此选B。
题号:136.
You have two database servers SEMP and SACCT. The database in the SEMP server maintains the employee information and the database in the SACCT server maintains the accounts payable information.The
employees submit the expense reports to the accounts payable department. A user of the accounts payable database wants to extract the employee information from the database in the SEMP server for cross-verification.
Which schema object enables the user to access the information from the remote database?
A.Cluster
B.Database link
C.Mapping table
D.Materialized view
Answer: B
深蓝浅析:
为了实现两个数据库数据的关联,这里须要使用Database link。
题号:137.
Your database instance is currently configured to support 1,500 connections. The Web application that uses the database allows a large number of users to work with the database simultaneously.
Some users of the Web application do not interact with the server all the time.
You want to increase the scalability by configuring the database instance to handle more connections. As a DBA, which configuration would you set to support more than 1,500 connections at a time?
A.You would configure more listeners for the database.
B.You would configure the database in shared server mode to use the connection pooling feature.
C.You would increase the value of the PGA_AGGREGATE_TARGET initialization parameter that assigns more session memory to users.
D.You would decrease the value of the PRIVATE_SGA resource limit in the profiles used by the users to accommodate more session information.
Answer: B
深蓝浅析:
这里为了扩大用户连接数。DBA能够使用共享server模式。来建立一个连接池来实现连接比較多的用户的任务,但这样的连接是以牺牲一部分性能为代价的。
声明:原创作品。出自 “深蓝的blog” 博客。欢迎转载。转载时请务必注明出处。否则追究版权法律责任。
深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/39780805
版权声明:本文博客原创文章。博客,未经同意,不得转载。