文档章节

Java Web开发入门 - 第3章 Tomcat

抢小孩糖吃
 抢小孩糖吃
发布于 2016/08/19 16:35
字数 4973
阅读 175
收藏 3

#Tomcat安装与运行 Web服务器完成底层的网络处理,包括HTTP协议报文格式的编解码、管理具体web请求处理线程等操作。
Tomcat目前最流行最常见的基于Java的web应用服务器软件。 ##Tomcat Apache Tomcat 官网

  • Apache软件基金会出品
  • 开源软件
  • 源代码是Java写的 ##安装
  • 依赖JDK,保证Java已经安装
  • Tomcat 安装
    • Windows平台安装
    • Linux和Mac平台,下载压缩包解压运行
      配置环境变量CATALINA_HOME CATALINA是Tomcat的组成部分,CATALINA这个组件会调用用户的Java代码。在实际部署的某些情况下是可以不配置该环境变量。当一个服务器配置多个Tomcat的时候,这个环境变脸必须配置。

##Tomcat安装过程 ###下载Tomcat 7.0.x 通过官网Tomcat 7 Software Downloads页面,我们可以看到zip包。通过超级链接获取7.0.77版本的zip下载路径为http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.70/bin/apache-tomcat-7.0.70.zip
如果Linux系统连接网络,则可以通过如下命令进行下载:

 wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.70/bin/apache-tomcat-7.0.70.zip

如果没有联网可以在Windows下载Tomcat,通过FileZilla软件发送安装包到Linux ###解压缩Tomcat Tomcat官网提供了两种压缩包zip和tar.gz方式。
Windows系统可以下载7zip软件或者WinRAR软件进行解压缩。
Linux系统zip方式解压缩命令:

yum install unzip -y
unzip apache-tomcat-7.0.70.tar.gz

Linux系统tar.gz方式解压缩命令:

tar xzvf apache-tomcat-7.0.70.tar.gz

###配置CATALINA_HOME环境变量 ####Linux 进入解压缩后的apache-tomcat-7.0.xx的目录,在目录下执行

export CATALINA_HOME=/home/zhanpeng/build/tomcat/apache-tomcat-7.0.70

通过echo $CATALINA_HOME检查所配置的路径是否正确。

zhanpeng@GE70:~/build/tomcat/apache-tomcat-7.0.70$ echo $CATALINA_HOME
/home/zhanpeng/build/tomcat/apache-tomcat-7.0.70

####Windows设置环境变量

set CATALINA_HOME=D:\build\tomcat\apache-tomcat-7.0.70

检查环境变量

echo %CATALINA_HOME%

####Mac OS X设置环境变量 两种配置方式:第一种全局配置,编辑/etc/profile,第二种只应用到当前用户,编辑~/.bash_profile。如果要应用环境变量,则需要使用source /etc/profile或者source ~/.bash_profile进行启用,或者重新登陆用户或者重启计算机。 ##启动Tomcat

  • *nix平台
    • $CATALINA_HOME/bin/startup.sh
    • $CATALINA_HOME/bin/catalina.sh start
  • Windows平台
    • %CATALINA_HOME%\bin\startup.bat
    • %CATALINA_HOME%\bin\catalina.bat start

###演示linux tomcat启动过程 ####1.检查环境变量

zhanpeng@GE70:~/build/tomcat/apache-tomcat-7.0.70$ echo $CATALINA_HOME
/home/zhanpeng/build/tomcat/apache-tomcat-7.0.70

####2.修改Tomcat执行权限 如果解压缩tomcat这个时候执行,则没有权限

echo $CATALINA_HOME
$CATALINA_HOME/bin/startup.sh
bash: /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70/bin/startup.sh: Permission denied

修改权限:

$chmod +x $CATALINA_HOME/bin/*

执行:

 $CATALINA_HOME/bin/startup.sh
Using CATALINA_BASE:   /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70
Using CATALINA_HOME:   /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70
Using CATALINA_TMPDIR: /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70/bin/bootstrap.jar:/home/zhanpeng/build/tomcat/apache-tomcat-7.0.70/bin/tomcat-juli.jar
Tomcat started.

通过浏览器查看到如下界面: 输入图片说明 通过浏览器进行查看 注意:如果不是本机打开浏览器访问,远程打开Tomcat,注意Linux或者Windows的防火墙配置,开发8080端口(如果修改Tomcat端口请自行注意)。如果对防火墙配置有问题,开发时可以关闭防火墙,进行开发。

##Tomcat资源 静态资源 动态资源,Servlet课程

##动态资源与静态资源概念 ###目录结构 输入图片说明 ###静态资源SoybeanMilk.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>Soybean Milk</h1>
</body>
</html>

###动态资源NoodlesServlet.java 手动编译在WEB-INF/classes/com.netease下 idea编译在src/com.netease下编译

package com.netease;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by zhanpeng on 16-8-20.
 */
public class NoodlesServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException {

        PrintWriter writer = response.getWriter();

        String vegetable = request.getParameter("vegetable");

        if(vegetable == null)
            vegetable = "Tomato";

        writer.println("<html><body>");
        writer.println("<h1> Noodles with " + vegetable + "</h1>");
        writer.println("</html></body>");
    }
}

###添加servlet到web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    
    <display-name>Restaurant</display-name>
    <servlet>
        <servlet-name>noodles</servlet-name>
        <servlet-class>com.netease.NoodlesServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>noodles</servlet-name>
        <url-pattern>/noodles</url-pattern>
    </servlet-mapping>
</web-app>

###编译或者添加tomcat类库运行 ####手动编译

javac -cp /home/zhanpeng/build/tomcat/apache-tomcat-7.0.70/lib/servlet-api.jar WEB-INF/classes/com/netease/NoodlesServlet.java

####添加tomcat类库 输入图片说明 ###静态资源

http://localhost:8080/SoybeanMilk.html

不管我们如何加入参数,页面不变
我们事先准备好的,叫做静态资源,静态资源像图片常见的文档。 ###动态资源

http://localhost:8080/noodles

显示Noodles with Tomato

http://localhost:8080/noodles?vegetable=Apple

显示Noodles with Apple
动态页面根据我们参数的不同,会显示不同内容页面。根据不同的请求返回不同结果。

##关闭Tomcat

  • *nix平台
    • $CATALINA_HOME/bin/shutdown.sh
    • $CATALINA_HOME/bin/catalina.sh stop
  • Windows平台
    • %CATALINA_HOME%\bin\shutdown.bat
    • %CATALINA_HOME%\bin\catalina.bat stop

#Tomcat的组成、架构与配置部署 ##Tomcat目录结构 输入图片说明

  • bin 目录:用于存放tomcat执行脚本,例如启动关闭,同时还提供脚本依赖的包
  • conf 目录:放置tomcat配置文件
  • lib目录:存放tomcat的依赖库,也可以把共同依赖包放到这里
  • logs 目录:存放log日志
  • temp 目录:存放临时文件。web应用产生的临时文件
  • webapps目录:默认的应用部署目录
  • work目录:tomcat运行的 供web应用使用。
  • LICENSE许可证文件

###bin目录 输入图片说明

####启动脚本 JVM启动参数配置:可以使用环境变量

  • 环境变量JAVA_OPTS配置
  • *常见参数 -server -Xms512m -Xmx512m -server告诉JVM这个是服务,由JVM以server的方式进行优化 -Xms -Xmx是设置JVM的堆大小 -Xms设置初始堆 -Xmx设置堆最大值
export JAVA_OPTS="-server =xms2048m -Xmx2048m"
echo $JAVA_OPTS

如果想要永久有效需要写入到~/.bashrc下 ###conf目录 输入图片说明 最主要的配置文件为server.xml ####server.xml server.xml结构

<?xml version='1.0' encoding='utf-8'?>
<Server >
    <Listener></Listener>

    <Service name="Catalina">
        <Connector></Connector>
        <Connector></Connector>
        <Engine>
            <Host>
                <Context></Context>
            </Host>
        </Engine>
    </Service>
</Server>

Server下面可以有多个Service和多个Connector。一个Service必须有一个Engine,Engine是处理Connector接收到的数据内容。JDK的java由Engine执行。Engine里面有多个Host,Host是虚拟主机,请求加入不同的Host头,跳转到。一个Host可以有多个Context。Context为Web应用。 service我们叫做Container(容器)。整个Server就是Tomcat。

  • Connector
    • Coyote
    • 默认使用BIO Connector,使用Java IO进行处理,阻塞式IO
  • Container
    • Catalina实现容器的组件
    • Servlet课程

##请求处理流程 浏览器发送请求,由Connector接收处理socket数据信息。Container根据Connector解析内容生成具体的响应。 输入图片说明

#Tomcat的Connector及线程池配置 ##Connector参数配置

  • port端口号
  • address配置Connector监听哪几个IP地址的响应
  • protocol默认为protocol="HTTP/1.1",涉及调优才进行调整
  • connectionTimeout服务端当连接占用不发送请求的关闭时间,单位ms
  • acceptCount指系统繁忙,如果没有空闲线程,则配置队列长队,默认值为100。如果超过承载数则拒绝连接(没有在默认文档中找到)
  • maxConnections默认最大连接数,当使用的是默认的BIO Connector时,最大连接数是和线程池最大值。为-1时,不限制连接。 ##线程池 事先创建一定数据的线程,当有任务时,从线程池中取出,当用完后在释放回连接池内。
  • 最小空闲线程数minSpareThreads
  • 最大线程数maxThreads 当请求处理数小于最小空闲线程数时,使用最小空闲线程。当超过时,动态增加线程数据直到到达最大线程数。当请求处理结束,自动释放资源,则称弹性线程池。Tomcat使用的就是弹性线程池。
    ##配置 修改apache-tomcat-x.0.xx/conf/server.xml 修改默认端口和过期时间
<Connector port="8181" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

默认没有配置线程池,配置中被注释掉了

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>

应用Connector应用Executor,注意要和Executor name相同

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               executor="tomcatThreadPool"
               redirectPort="8443" />

重启Tomcat,查看效果。 命令查看请求:

curl http://localhost:8080/noodles
<html><body>
<h1> Noodles with Tomato</h1>
</html></body>

命令占用请求:
客户端0:

telnet localhost 8181
GET /noodles HTTP/1.1

客户端1:

telnet localhost 8181
GET /noodles HTTP/1.1

当线程池为1时,客户端0阻塞线程,则客户端1都无法获取结果;客户端0结束,客户端1也会执行完成。 ##线程池配置 *Executor配置线程池

    • minSpareThreads
    • maxThreads
  • Connector配置线程池
    • 制定依赖的线程池配置
    • 直接制定线程池配置参数
      • minSpareThreads、maxThreads 当Connector及配置Executor也配置线程池参数,则使用Executor配置。

#Tomcat日志配置与war包部署 ##Tomcat日志 服务发生中断,则需要知道

  • 日志的作用
    • Tomcat运行情况获知
    • 调试利器
  • Tomcat日志分类
    • 系统运行日志 - 捕获Tomcat系统错误
    • 访问日志 - 记录用户请求的访问,根据日志统计一共有多少次请求
    • 应用日志 - 程序日志

###访问日志配置文件server.xml

<!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

###修改日志文件命名 ####日志实现AccessLogValve ####direcory Valve的directory日志存放目录 ####pattern prefix日志文件的前缀 ####suffix suffix日志文件的后缀 ####pattern pattern指日志的格式。
pattern内%r指HTTP 请求行;%s HTTP相应号;%t访问时间;%m请求方法,%a请求的IP地址;%s用户响应码;%b服务端下发多少字节;%{User-Agent}i指User-Agent;&quot;

###日志文件切割

               fileDateFormat="yyyy-MM-dd.HH." #按照参数进行切割
               rotatable="true" #是否切分

修改后的日志配置

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="hava_access_log." suffix=".log"
               fileDateFormat="yyyy-MM-dd.HH."
               rotatable="true"
               pattern="method: %m,client ip: %a,time: %t,&quot;%r&quot; statusCode: %s,byteSent: %b,User-Agent: %{User-Agent}i" />

重启Tomcat后,产生日志文件hava_access_log.2016-08-20.14.35.log,Chrome访问内容为:

method: GET,client ip: 127.0.0.1,time: [20/Aug/2016:14:36:30 +0800],"GET / HTTP/1.1" statusCode: 200,byteSent: 11418,User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36

curl访问内容为:

method: GET,client ip: 127.0.0.1,time: [20/Aug/2016:14:37:43 +0800],"GET / HTTP/1.1" statusCode: 200,byteSent: 11418,User-Agent: curl/7.35.0

##Tomcat文档 Tomcat 7 文档

##Tomcat部署Web应用

  • Web应用程序结构
    • Servlet课程
  • 手动部署
  • 打war包,Web应用打war包,方便程序共享 ###手动打包 在idea的输出目录out内,可以看到war_exploded目录,通过jar cvf package.war .进行打包
jar cvf Restaurant.war .
added manifest
adding: SoybeanMilk.html(in = 143) (out= 110)(deflated 23%)
adding: index.jsp(in = 295) (out= 224)(deflated 24%)
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/netease/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/netease/NoodlesServlet.class(in = 1371) (out= 687)(deflated 49%)
adding: WEB-INF/web.xml(in = 632) (out= 270)(deflated 57%)
zhanpeng@GE70:~/Workspace/J2ee/TomcatStudy/out/artifacts/TomcatStudy_war_exploded$ 

注意:这种方式会把隐藏文件也打包到war包内。 把war包放到webapps目录下,可以直接访问。Tomcat会自动解压缩war包内容。 #附录 ##Tomcat FAQ ###Q:Tomcat使用哪个版本的?
A: 目前Tomcat最新开发版是9.0.x,最新稳定版是8.0.x,一般在生产环境使用比较多的版本还是7.0.x。本微专业选择的Tomcat版本是7.0.x。更新的版本之间不过是实现了更多的一些新特性,我们的微专业中并没有涉及到这些新特性,因此7.0.x是足够的

###Q: 我在Windows下,Tomcat怎么安装以及使用?
A:

  1. 因为Java是跨平台的,因此,在Windows下一样可以使用视频中讲述的方式进行安装,然后通过命令行的方式来启动停止Tomcat
  2. 针对于Windows,Tomcat还提供了更简单的方式,大家可以直接下载Tomcat的Windows Installer,http://tomcat.apache.org/download-70.cgi, 在这个页面上下载Windows Service Installer这个,然后直接双击安装就好了,同时这个Installer还为大家提供了一个图形界面的工具,可以完成Tomcat的配置、启动以及停止
  3. 在Windows vista以后的Windows版本中,由于增加了UAC,因此在双击Tomcat的安装文件的时候,可能需要提供管理员权限,具体操作为右键,选择使用管理员权限运行

###Q: 我完全不会Linux,在windows下,跟老师的演示环境不一样,怎么办?
A:

  1. Java语言是跨平台的,Tomcat也是跨平台的,无论是在windows,还是在Linux下,他们的使用方法,命令行参数含义等等都是一致的
  2. 即使是在linux操作,也无非是建立新文件,建立文件夹,手写点代码而已,使用的都是一些简单的命令。在Windows下一样可以使用鼠标点击完成建立新文件,建立文件夹等操作,你可以使用记事本,notepad++等等,任意一款编辑器写代码。
  3. 对于Tomcat的启动停止,一样可以不用命令行,Windows提供了通过Windows Service Installer进行安装的方式,可以通过图形界面进行Tomcat的启动停止操作
  4. 建议大家稍微学习一点Linux操作,这是作为一个服务端开发者的基本技能,任何知识都是从不会到会的

###Q: 我都跟老师做的一样,为什么出错了?
A: 当大家遇到错误的时候,希望能按下面给出的步骤进行排查

  1. 作为初学者,大家最常遇到的问题就是拼写错误,因此首先检查有没有出现拼写错误。
  2. 如果没查出来错误,先尝试去理解报错来的错误信息,一般情况下,错误信息中都会给出解决建议
  3. 借助搜索引擎,贴出报错信息,搜索解决方案,stackoverflow之类的网站上,往往就有你要的解决方案
  4. 实在搞不定,到论坛上看看有没有同学已经遇到了类似的问题,并且已经有了解决方案
  5. 到论坛发帖,或直接通过邮件等方式将问题发给老师 在实际工作中,遇到问题解决问题是一个比较重要的能力。因此在学习过程中,就要有意识地去提高自己这方面的能力。我们不希望大家一旦遇到问题就立即提问,因为在实际工作中,你的提问是不会有人给你回答的。大家可以先尝试解决,在尝试解决问题的过程中,往往大家也能学到一些其他方面的知识。当实在搞不定的时候,再告诉老师,我们会在第一时间为大家解答。

###Q: 通过一些书和其他教程,我学会了在eclipse中直接创建一个Web项目,跟这里纯手动创建一个web项目相比有一些疑问:

  1. eclipse 默认创建tomcat7的项目里面并没有web.xml文件,那么tomcat是如何找到相关servlet的?
  2. 通过eclipse创建的项目中会有一个叫WebContent的目录,这个和我们纯手动创建的Restaurant项目有何不同?
  3. 为什么将eclipse创建的项目手动拷贝到tomcat7.0.x下webapps目录下,启动后无法访问里面的servlet?我应该如何访问这个servlet?

A:

  1. eclipse 默认创建tomcat7的项目里面并没有web.xml文件,那么tomcat是如何找到相关servlet的? 如果没有servlet,仅仅是jsp加上静态文件的话,web.xml是可以省略的 即使生成了servlet,在新的servlet规范里面,也支持了使用Annotation的方式来配置servlet,跟使用web.xml的方式是等价的 你看一下生成的类上面应该有 @WebServlet 的定义

  2. 通过eclipse创建的项目中会有一个叫WebContent的目录,这个和我们手动创建的Restaurant项目有何不同? 源码层面的文件结构可以千差万别,但是最终部署的时候,项目文件结构必须满足servlet规范。只是eclipse默认创建的项目是这样做的而已,eclipse默认创建的项目跟我们手动创建的Restaurant项目没有啥本质不同。后面我们还会讲到Maven,让Maven来管理我们的Web项目,他们最终编译打包后的文件结构是一样的。

  3. 为什么将eclipse创建的项目手动拷到tomcat7.0.65下webapps目录下,启动后 无法访问里面的servlet 我应该如何访问这个servlet? 估计你是搞混了源码跟编译打包后的二进制。你把eclipse创建的项目编译后打成一个war包,然后把这个war包放到webapps目录下,就可以跑了 另外,war包本身是一个zip格式的压缩包,你可以把它解压开,然后看一下里面的内容,以及里面的文件结构,跟我们Restaurant的文件结构一定是一致的,所有这一切工作都是eclipse在背后默默帮你完成了 我们在Restaurant里面,只是把这一切都纯手动化了,为了是让大家真正地明白一个Web项目在部署的时候长什么样子,而不是简单地告诉你怎样在IDE里面做

###Q: 我使用了网易蜂巢提供的Java Web镜像,里面的安装的tomcat7的目录结构怎么找不到? A: 我们在网易蜂巢提供的Java Web镜像,其是一个Debian系统,里面的tomcat7是使用包管理工具apt-get/aptitude 进行安装管理的。Debian在打包tomcat7的时候,遵循了其系统的管理,那就是对任何一个软件,其不同的功能的文件会分到不同的目录中,对于tomcat7,具体对应如下:
bin -> /usr/share/tomcat7/bin
lib -> /usr/share/tomcat7/lib
conf -> /var/lib/tomcat7/conf
webapps -> /var/lib/tomcat7/webapps
logs -> /var/lib/tomcat7/logs
work -> /var/lib/tomcat7/work

对于启动/停止 tomcat,请直接使用已经封装好的服务方式,使用的命令为

service tomcat7 start service tomcat7 stop

想看运行状态,可以使用命令

service tomcat7 status

###Q: 我运行Tomcat报错,Class com.netease.NoodlesServlet is not a Servlet,怎么办? A: 很多同学会纳闷,我的类明明是从HttpServlet继承下来的,怎么就不是Servlet了。这个是因为JVM在确定一个类的时候,不仅仅根据这个类的名字,还有加载这个类的类加载器,只有这两个都一致的时候,才认为是同一个类。由于在JVM在不同的加载阶段使用不同的类加载器,Tomcat内部也实现了自己的类加载器,造成这个问题的原因就是类加载器冲突造成的。解决方案如下:

  1. 确认一下在pom.xml配置的javax.servlet-api这个依赖的scope是provided
  2. 确认没有把servlet-api.jar 这个文件放到 java的 lib/ext目录下,如果有放置,删除掉
  3. 确认一下有没有配CLASSPATH环境变量,并且CLASSPATH中有指向servlet-api.jar这个文件。如果有配置,清除掉
  4. 由于这类错误还有依赖版本不统一,原来安装的一些软件遗留等原因造成,虽然表现出来的症状一样,但是实际情况可能比上面说出来的情况还要多一些。在搞不定的时候,可以尝试重装大法,重装你的JDK
  5. 关于类加载器以及Java的一些路径的知识,可以参考这篇文章http://www.ibm.com/developerworks/cn/java/j-classpath-windows/, 里面有一句话“强烈建议您在编译和运行时总是显式地指定类路径”,这个也是为什么在演示编译的时候,是通过指定-cp(与-classpath等价)参数,而不是通过其他方式,引入对servlet-api.jar的依赖

© 著作权归作者所有

抢小孩糖吃

抢小孩糖吃

粉丝 74
博文 255
码字总数 245265
作品 0
东城
程序员
私信 提问
Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区
2018/05/09
0
0
【Java学习路线】新手该如何一步步的学习 Java

新手该如何一步步的学习 Java? 如果真的想学Java,最好要循序渐进,有章有法的学习它! 今天小慕就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容。 首先,给大家分享一张以 企业...

Eddie_yang
2018/11/15
2.1K
0
web前端、c++、项目管理、java、php书籍10-40/本,转让

本人因转行,又因经济困难,所以转让一下书籍。按标价出售,人在北京。联系qq:602505 可在东城区、中关村、回龙观等地当面交易。 书新旧程度全部在9成新以上。 点击书名查看书籍介绍和原价。...

匿名网友
2011/02/24
1K
17
java 7 入门书籍

一、Java从入门到精通 《Java从入门到精通(第3版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Java语言进行程序开发需要掌握的知识。 《Java从入门到精通(第3版...

modernizr
2014/05/15
7.5K
9
【有奖书评】JAVA 7来袭,还看 Java 你就OUT了

从1995年至今,Java已经超过15个年头,经过这些年的演进,Java已不仅是个程序语言,也代表了解决问题的平台(Platform),更代表了原厂、各个厂商、社群、开发者与用户沟通的成果。若仅以程序语...

louise
2012/08/31
12.5K
123

没有更多内容

加载失败,请刷新页面

加载更多

如何编写高质量的 JS 函数(1) -- 敲山震虎篇

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ 作者:杨昆 一千个读者,有一千个哈姆雷特。 此系列文章将会从函数的执行机制、鲁棒性、函...

vivo互联网技术
54分钟前
5
0
学会这5个Excel技巧,让你拒绝加班

在网上,随处都可以看到Excel技巧,估计已看腻了吧?但下面5个Excel技巧会让你相见恨晚。关键的是它们个个还很实用 图一 技巧1:快速删除边框 有时当我们处理数据需要去掉边框,按Ctrl+Shif...

干货趣分享
今天
11
0
JS基础-该如何理解原型、原型链?

JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个...

OBKoro1
今天
10
0
高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
15
0
OSChina 周一乱弹 —— 熟悉的味道,难道这就是恋爱的感觉

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoshiyue :好久没分享歌了分享张碧晨的单曲《今后我与自己流浪》 《今后我与自己流浪》- 张碧晨 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
3.3K
25

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部