tomcat企业级Web应用服务器配置与实战

  环境背景:公司业务经过长期发展,有了很大突破,已经实现盈利,现公司要求加强技术架构应用功能和安全性以及开始向企业应用、移动APP等领域延伸,此时原来开发web服务的php语言已经不适应新的场景,需要上java技术架构,现要求你根据公司需要,实现基于java平台的web应用服务选型、搭建、实现和应用,此时你如何选择?

  项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html

  本篇实战所需的包,都存放在我的网盘中 http://pan.baidu.com/s/1c2B7BO0,需要的私聊我。

实战一:在linux上,安装tomcat

1、下载安装java所需要的环境和开发工具包

(1)Java 所需要的环境和开发工具包介绍

JRE: Java Runtime Environment

JDK:Java Development Kit JRE

JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。

JDK顾名思义是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。如果你需要运行java程序,只需安装JRE就可以了。如果你需要编写java程序,需要安装JDK。JRE根据不同操作系统(如:windows,linux等)和不同JRE提供商(IBM,ORACLE等)有很多版本,最常用的是Oracle公司收购SUN公司的JRE版本。

(2)安装相应版本的rpm包 jdk-VERSION-OS-ARCH.rpm

yum -y localinstall jdk-8u144-linux-x64.rpm

centos7系统自带:jdk-1.8.0_25-linux-x64.rpm

java -version 显示java程序的版本信息

(3)安装完成后,要配置JAVA_HOME环境变量

vim /etc/profile.d/java.sh

  1. export JAVA_HOME=/usr/java/jdk1..0_144
  2. export JRE_HOME=$JAVA_HOME/jre
  3. export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

2、下载安装tomcat

方法一:二进制安装(推荐)

(1)从官网下载tomcat二进制安装包 http://tomcat.apache.org/

https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.23/bin/

(2)解包,设置目录

① 解包

tar xvf apache-tomcat-8.5.11.tar.gz -C /usr/local/

② 为了方便管理,设置软连接,若以后换版本了,可以很容易切换

ln -s /usr/local/apache-tomcat-7.0.78/ /usr/local/tomcat

(3)设置环境配置管理脚本

vim /etc/profile.d/tomcat.sh

  1. export CATALINA_BASE=/usr/local/tomcat
  2. export PATH=$CATALINA_BASE/bin:$PATH
  3. source /etc/profile.d/tomcat.sh 执行加载环境配置

方法二:yum安装

(1)安装

  1. yum install tomcat -y #安装tomcat主程序
  2. yum install -y tomcat-admin-webapps tomcat-docs-webapp tomcat-webapps #安装tomcat对应的页面
  3. mkdir /var/lib/tomcat/webapps/{ROOT,test}/{WEB-INF,META-INF,classes,lib} -pv #创建页面所需要的工作目录

(2)rpm包安装的程序环境:

配置文件目录:/etc/tomcat

主配置文件:server.xml

webapps存放位置:/var/lib/tomcat/webapps/

examples

manager

host-manager

docs

Unit File:tomcat.service

环境配置文件:/etc/sysconfig/tomcat #调整jdk内存使用大小等初始值

3、启动tomcat

(1)catalina.sh start

(2)测试本地8080端口是否正常监听

curl -I 127.0.0.1:8080

通过浏览器访问测试(需指定8080端口)

实战二:基于tomcat布署一个开源java产品

1、去网上下载开源Java 代码

可以去开源中国下载自己需要的https://www.oschina.net/

我已经下好一个,需要的私密我http://pan.baidu.com/s/1c2B7BO0

2、解包、布署和查看使用说明

① unzip zchuanzhao-jeesns-master.zip

② mv /jeesns/war/jeesns.war .../webapps 把jeesns.war移到你的tomcat的webapps 下

如果你是自动布署,会自动在/webapps 下生成jeesns目录;若不是,可以自己unzip 解包,布署

autoDeploy="true" 是自动布署

③ cat README.md 有详细的操作过程

3、同步数据到数据库

(1)在数据库创建一个存放的库

MariaDB [(none)]> create database along;

(2)把数据同步到数据库

cd /jeesns/jeesns-web/database/

mysql -uroot -p -D along < jeesns.sql

4、修改数据库连接

vim /webapps/jeesns/WEB-INF/classes/jeesns.properties

修改数据库和登录用户和密码

5、访问页面,布署成功

① 登录首页 http://192.168.30.107:8080/jeesns

② 进入后台管理 http://192.168.30.107:8080/jeesns/manage/login

用户名:admin

密码:jeesns

③ 登录后台成功!

这个设计的还是挺高级的!!! 大家可以尝试一番

实战三:实现LNMT,nginx代理tomcat

分析:就是由nginx 代理tomcat 来实现的

1、直接在nginx 上设置跳转

vim /etc/nginx/nginx.conf

  1. location / {
  2. proxy_pass http://192.168.30.107:8080;
  3. }
  4. location ~* \.(jsp|do)$ {
  5. proxy_pass http://192.168.30.107:8080;
  6. }

2、访问测试,http://192.168.30.107/

访问80端口,能代理到8080端口

3、实现集群代理服务

(1)先在http 段定义

vim /etc/nginx/nginx.conf

  1. upstream tomcat_srv {
  2. server 192.168.30.107: weight=;
  3. server 192.168.30.7: weight=;
  4. } 

(2)再在server 段定义location

  1. location / {
  2. proxy_pass http://tomcat_srv;
  3. }
  4. location ~* \.(jsp|do)$ {
  5. proxy_pass http://tomcat_srv;
  6. }

(3)创建测试页面

① 在server1 上定义一个页面

vim webapps/test/index.jsp

  1. <%@ page language="java" %>
  2. <%@ page import="java.util.*" %>
  3. <html>
  4. <head>
  5. <title>Test Page</title>
  6. </head>
  7. <body>
  8. <% out.println("hello world");%>
  9. </body>
  10. </html>

② 在server2 上定义一个页面

vim webapps/test/index.jsp

  1. <%@ page language="java" %>
  2. <%@ page import="java.util.*" %>
  3. <html>
  4. <head>
  5. <title>Test Page</title>
  6. </head>
  7. <body>
  8. <% out.println("hello world2");%>
  9. </body>
  10. </html>

(4)页面访问测试

轮询出现

实战四:LNMT的会话保持原理及基于ip_hash实现

1、原理:有三种类型的方法,实现会话保持的方法

(1) session sticky(贴) 基于hash 和cookie 来实现会话保持,简单的负载均衡算法

① 基于source_ip(源地址hash)

  nginx: ip_hash 、 haproxy: source 、 lvs: sh

② 基于cookie nginx基于cookie实现,需加载cookie模块,cookie 力度更新

  nginx:sticky 、haproxy: cookie

(2) session cluster:delta session manager 基于tomcat集群会话保持

分析:tomcat自身带的机制 session cluster,基于组播的方式,一个tomcat 被用户登录访问,记录session通过组播给集群中的其他机器复制一份;那么当用户再次访问时,每个机器都有session 会话记录;从而实现了会话保持

(3) session server:redis(store), memcached(cache) 共享存储

分析:新建立一个存放各个tomcat session记录的server,每台tomcat服务器都将自己的session记录在这个服务器中,用户再次访问,每台tomcat 都从这个server中获取;实现会话保持

2、简单实现基于ip hash 实现会话保持

vim /etc/nginx/nginx.conf 只需加一条ip_hash即可

upstream tomcat_srv {

  1. upstream tomcat_srv {
  2. ip_hash;
  3. server 192.168.30.107: weight=;
  4. server 192.168.30.7: weight=;
  5. }

3、测试

访问页面,一直匹配到107的server 上,没有轮询;会话保持成功

实战四:基于tomcat会话集群实现LNMT的会话保持

原理:Tomcat集群的会话管理器,它通过将改变了会话数据同步集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点

1、环境准备

 

机器名称

IP配置

服务角色

备注

nginx

192.168.30.107

代理服务器

开启代理功能

tomcat-srv1

192.168.30.106

web服务

配置集群会话

tomcat-srv2

192.168.30.7

web服务

配置集群会话

2、配置nginx代理

vim /etc/nginx/nginx.conf

  1. upstream tomcat_srv { #在http 段配置
  2. server 192.168.30.106: weight=;
  3. server 192.168.30.7: weight=;
  4. }
  5.  
  6. location / { #在server 段配置
  7. proxy_pass http://tomcat_srv;
  8. }
  9. location ~* \.(jsp|do)$ {
  10. proxy_pass http://tomcat_srv;
  11. }

systemctl start nginx 开启服务

3、tomcat 集群会话的配置

注意:两台tomcat-srv的配置是一模一样的,除了测试的页面设置不同

cd /usr/local/tomcat/ 进入自己的tomcat 的目录下

vim conf/server.xml 在Engine 引擎段中,添加下面代码,注意:注释千万别加去

  1. <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions=""> 定义集群节点,“”表示异步
  2.  
  3. <Manager className="org.apache.catalina.ha.session.DeltaManager" 定义Manger采用DeltaManager 会话管理器
  4. expireSessionsOnShutdown="false" 一个节点关闭,不影响集群其他session
  5. notifyListenersOnReplication="true"/> 复制、删除操作通知session listener
  6.  
  7. <Channel className="org.apache.catalina.tribes.group.GroupChannel">
  8. <Membership className="org.apache.catalina.tribes.membership.McastService"
  9. address="228.0.0.4" port="" frequency="" dropTime=""/>
  10. <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
  11. address="auto" port="" autoBind="" selectorTimeout="" maxThreads=""/>
  12. <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
  13. <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
  14. </Sender>
  15. <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
  16. <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
  17. </Channel>
  18.  
  19. <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter="/"/>
  20. <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
  21. <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
  22. </Cluster>

4、配置注释

(1)Cluster配置:

Cluster(集群,族) 节点,如果你要配置tomcat集群,则需要使用此节点.

className 表示tomcat集群时,之间相互传递信息使用那个来实现信息之间的传递.

channelSendOptions可以设置为2、4、8、10,每个数字代表一种方式

  2 = Channel.SEND_OPTIONS_USE_ACK(确认发送)

  4 = Channel.SEND_OPTIONS_SYNCHRONIZED_ACK(同步发送)

  8 = Channel.SEND_OPTIONS_ASYNCHRONOUS(异步发送)

在异步模式下,可以通过加上确认发送(Acknowledge)来提高可靠性,此时channelSendOptions设为10,半同步

例:

  1. <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="">

(2)Manager

(a)Manager介绍

Manger对象用于实现HTTP会话管理的功能,Tomcat中有4种Manger的实现:

① StandardManager

Tomcat6的默认会话管理器,用于非集群环境中对单个处于运行状态的Tomcat实例会话进行管理。当Tomcat关闭时,这些会话相关的数据会被写入磁盘上的一个名叫SESSION.ser的文件,并在Tomcat下次启动时读取此文件。

② PersistentManager

当一个会话长时间处于空闲状态时会被写入到swap会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。

DeltaManager

用于Tomcat集群的会话管理器,它通过将改变了会话数据同步集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。

④ BackupManager

用于Tomcat集群的会话管理器,与DeltaManager不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点

(b)Manager配置

  1. className-指定实现org.apache.catalina.ha.ClusterManager接口的类,信息之间的管理
  2. expireSessionsOnShutdown-设置为true时,一个节点关闭,将导致集群下的所有Session失效
  3. notifyListenersOnReplication-集群下节点间的Session复制、删除操作,是否通知session listeners

(3)Channel 频道的介绍和配置

(a)介绍

Channel是Tomcat节点之间进行通讯的工具。Channel包括4个组件:

  Membership:集群的可用节点列表

  Receiver :接收器,负责接收消息

  Sender :发送器,负责发送消息

  Interceptor :Cluster的拦截器

(b)Membership 配置

① Membership:维护集群的可用节点列表,它可以检查到新增的节点,也可以检查到没有心跳的节点

② className-指定Membership使用的类

③ address-组播地址

④ port-组播端口

⑤ frequency-发送心跳(向组播地址发送UDP数据包)的时间间隔(单位:ms)。默认值为500

⑥ dropTime-Membership在dropTime(单位:ms)内未收到某一节点的心跳,则将该节点从可用节点列表删除。默认值为3000

注:组播(Multicast):一个发送者和多个接收者之间实现一对多的网络连接。

一个发送者同时给多个接收者传输相同的数据,只需复制一份相同的数据包。

它提高了数据传送效率,减少了骨干网络出现拥塞的可能性

相同组播地址、端口的Tomcat节点,可以组成集群下的子集群

例:

  1. <Membership className="org.apache.catalina.tribes.membership.McastService"
  2. address="228.0.0.4"
  3. port=""
  4. frequency=""
  5. dropTime=""/>

(c)Receiver 配置

Receiver : 接收器,负责接收消息

接收器分为两种BioReceiver(阻塞式)、NioReceiver(非阻塞式)

  className-指定Receiver使用的类

  address-接收消息的地址

  port-接收消息的端口

  autoBind-端口的变化区间

  如果port为4000,autoBind为100,接收器将在4000-4099间取一个端口,进行监听

  selectorTimeout-NioReceiver内轮询的超时时间

  maxThreads-线程池的最大线程数

例:

  1. <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
  2. address="auto"
  3. port=""
  4. autoBind=""
  5. selectorTimeout=""
  6. maxThreads=""/>

(d)Sender 配置

Sender : 发送器,负责发送消息

Sender内嵌了Transport组件,Transport真正负责发送消息

Transport:定义传输方式

Transport分为两种:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式)

例:

  1. <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
  2. <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
  3. </Sender>

(e)Interceptor 配置

Interceptor : Cluster的拦截器

TcpFailureDetector-网络、系统比较繁忙时,Membership可能无法及时更新可用节点列表,此时TcpFailureDetector可以拦截到某个节点关闭的信息,并尝试通过TCP连接到此节点,以确保此节点真正关闭,从而更新集群可以用节点列表

MessageDispatch15Interceptor-查看Cluster组件发送消息的方式是否设置为Channel.SEND_OPTIONS_ASYNCHRONOUS(Cluster标签下的channelSendOptions为8时)。 设置为Channel.SEND_OPTIONS_ASYNCHRONOUS时,MessageDispatch15Interceptor先将等待发送的消息进行排队,然后将排好队的消息转给Sender

例:

  1. <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
  2. <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>

(4)ClusterListener 配置

ClusterListener : 监听器,监听Cluster组件接收的消息

使用DeltaManager时,Cluster接收的信息通过ClusterSessionListener传递给DeltaManager

例:

  1. <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

5、创建测试页面

mkdir webapps/test

cd webapps/test

① 设置一个web.xml 的配置文件

mkdir WEB-INF

cp /usr/local/tomcat/conf/web.xml WEB-INF/

vim WEB-INF/web.xml 在</web-app>上加一行

<distributable/> 表示分布式

② vim session.jsp 创建测试页面,在tomcat-srv1上是TomcatA;在tomcat-srv1上是TomcatB

  1. <%@ page language="java" %>
  2. <html>
  3. <head><title>TomcatA</title></head> //TomcatA的标题
  4. <body>
  5. <h1><font color="blue">TomcatA </h1>
  6. <table align="centre" border="">
  7. <tr>
  8. <td>Session ID</td>
  9. <% session.setAttribute("abc","abc"); %>
  10. <td><%= session.getId() %></td>
  11. </tr>
  12. <tr>
  13. <td>Created on</td>
  14. <td><%= session.getCreationTime() %></td>
  15. </tr>
  16. </table>
  17. </body>
  18. </html>

6、测试

页面访问http://192.168.30.107/test/session.jsp;轮询,但是session ID是一样的,会话保持成功

已经会话保持

实战五:基于共享存储实现LNMT的会话保持

原理:新建立一个存放各个tomcat session记录的server,每台tomcat服务器都将自己的session记录在这个服务器中,用户再次访问,每台tomcat 都从这个server中获取;实现会话保持

1、环境准备

机器名称

IP配置

服务角色

备注

nginx

192.168.30.107

代理服务器

开启代理功能

tomcat-srv1

192.168.30.106

web服务

指向共享存储

tomcat-srv2

192.168.30.7

web服务

指向共享存储

memcached

192.168.30.6

共享存储

2、下载提供,实验所依赖的.jar包

memcached-session-manager项目地址,http://code.google.com/p/memcached-session-manager/, https://github.com/magro/memcached-session-manager

① 下载如下jar文件至各tomcat节点的tomcat安装目录下的lib目录中,寻找自己需要的版本号,tc的版本号要与tomcat版本相同。

  memcached-session-manager-1.8.3.jar

  memcached-session-manager-tc7-1.8.3.jar

  spymemcached-2.11.1.jar

  msm-javolution-serializer-1.8.3.jar

  javolution-5.4.3.1.jar

我已经下到了我的网盘,有需要的私聊 http://pan.baidu.com/s/1nvGFgKD

② 把这些包,上传到 lib 目录下

/usr/local/tomcat/lib

3、配置nginx代理

vim /etc/nginx/nginx.conf

  1. upstream tomcat_srv { #在http 段配置
  2. server 192.168.30.106: weight=;
  3. server 192.168.30.7: weight=;
  4. }
  5.  
  6. location / { #在server 段配置
  7. proxy_pass http://tomcat_srv;
  8. }
  9. location ~* \.(jsp|do)$ {
  10. proxy_pass http://tomcat_srv;
  11. } 

systemctl start nginx 开启服务

4、在server.xml 中配置

vim /usr/local/tomcat/conf/server.xml

  1. <Context path="/test" docBase="test" reloadable="true">
  2.   <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
  3.   memcachedNodes="192.168.30.106:11211"
  4.   requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
  5.   transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/>
  6. </Context>

5、和上实验一样,创建测试页面并测试

页面访问http://192.168.30.107/test/session.jsp;轮询,但是session ID是一样的,会话保持成功

已经会话保持

项目实战8—tomcat企业级Web应用服务器配置与会话保持的更多相关文章

  1. 项目实战8.1—tomcat企业级Web应用服务器配置与会话保持

    分类: Linux架构篇   tomcat企业级Web应用服务器配置与实战 环境背景:公司业务经过长期发展,有了很大突破,已经实现盈利,现公司要求加强技术架构应用功能和安全性以及开始向企业应用.移动A ...

  2. 项目实战12.2—企业级监控工具应用实战-zabbix操作进阶

    无监控,不运维.好了,废话不多说,下面都是干货. 流量党勿入,图片太多!!! 项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html 一.U ...

  3. 项目实战10.1—企业级自动化运维工具应用实战-ansible

    实战环境: 公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测 ...

  4. 项目实战12.1—企业级监控工具应用实战-zabbix安装与基础操作

    无监控,不运维.好了,废话不多说,下面都是干货. 警告:流量党勿入,图片太多!!! 项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html ...

  5. 项目实战15.1—企业级堡垒机 jumpserver一步一步搭建

    本文收录在Linux运维企业架构实战系列 环境准备 系统:CentOS 7 IP:192.168.10.101 关闭selinux 和防火墙 # CentOS 7 $ setenforce 0 # 可 ...

  6. 【WEB API项目实战干货系列】- WEB API入门(一)

    这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController.   创建 Web API 项目 在这里我们使用VS2013, .NET 4.5.1创建 ...

  7. 项目实战15.2—企业级堡垒机 jumpserver快速入门

    必备条件 硬件条件 ① 一台安装好 Jumpserver 系统的可用主机(堡垒机) ② 一台或多台可用的 Linux.Windows资产设备(被管理的资产) 服务条件 (1)coco服务 ① 鉴于心态 ...

  8. 【Robot Framework 项目实战 02】SeleniumLibrary Web UI 自动化

    前言 SeleniumLibrary 是针对 Robot Framework 开发的 Selenium 库.它也 Robot Framework 下面最流程的库之一.主要用于编写 Web UI 自动化 ...

  9. Linux运维项目实战系列

    Linux运维项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-项目实战2-实现基于LVS负载均衡集群的电商网站架构 2.1项目实战2.1-nginx 反向 ...

随机推荐

  1. VPS搭建离线下载服务器——后网盘时代

    动机 由于学习的需要,在国外某服务器厂商购买了vps服务(至于是哪个厂商就不说啦).但是呢,就算用作梯子,一个月1T的流量总是用不完.最经觉得自己营养充足,想找点电影看看. 无奈现在百度网盘的速度真的 ...

  2. iOS 之GCD串行和并发队列的理解

    dispatch_queue_t serialQueue = dispatch_queue_create("com.lai.www", DISPATCH_QUEUE_SERIAL) ...

  3. (2017浙江省赛E)Seven Segment Display

    Seven Segment Display Time Limit: 2 Seconds      Memory Limit: 65536 KB A seven segment display, or ...

  4. ssh密钥创建分发(端口号非22)&脚本实现自动创建分发密钥

    1.1 服务端端口号变化了,如何基于秘钥连接 1.1.1 环境准备 实验环境: [root@test ~]# cat /etc/redhat-release CentOS release 6.9 (F ...

  5. gbdt的面试要点总结-上篇

    1.简介 gbdt全称梯度下降树,在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一,在前几年深度学习还没有大行其道之前,gbdt在各种竞赛是大放异彩.原因大概有几个,一是效果确实挺不错.二是 ...

  6. 10.javaweb核心标签库详解

    一.JSTL简介及在项目中安装配置 1,  简介 使用JSTL标签的目的就是不希望jsp中出现java逻辑代码 分类 2,  JSTL的安装配置 首先将jar包中的各个标签库配置文件拷贝到项目WEB- ...

  7. 不想再被鄙视?那就看进来! 一文搞懂Python2字符编码

    程序员都自视清高,觉得自己是创造者,经常鄙视不太懂技术的产品或者QA.可悲的是,程序员之间也相互鄙视,程序员的鄙视链流传甚广,作为一个Python程序员,自然最关心的是下面这幅图啦 我们项目组一值使用 ...

  8. 八:Lombok 安装、入门 - 消除冗长的 java 代码

    Lombok 安装.入门 - 消除冗长的 java 代码 前言:    逛开源社区的时候无意发现的,用了一段时间,觉得还可以,特此推荐一下.    lombok 提供了简单的注解的形式来帮助我们简化消 ...

  9. 从编辑距离、BK树到文本纠错

    搜索引擎里有一个很重要的话题,就是文本纠错,主要有两种做法,一是从词典纠错,一是分析用户搜索日志,今天我们探讨使用基于词典的方式纠错,核心思想就是基于编辑距离,使用BK树.下面我们来逐一探讨: 编辑距 ...

  10. 用一条SQL语句查出每门课都大于80分的学生的姓名

    用一条SQL语句查出每门课都大于80分的学生的姓名,数据表结构如下: 建表SQL如下: ; -- ---------------------------- -- Table structure for ...