最近女朋友要准备软件测试的工作,看到了一个SQL的面试题,找我要答案,我觉得挺有意思,特分享出来。

题目要求结合2张基本表的内容,按要求输出需要的结果。

基本表A:

user_idname
1000张三
1001李四

基本表B:

key_iduser_idresult
00011000
00021001
00031001
00041000
00051000

输出的结果表C

姓名
张三21
李四11

解法一:观察结果表可以看到胜负数通过B表的result可以推到出来,姓名可以用user_id暂时替代,中间表B_result如下

user_idwinfail
100021
100111

生成中间表SQL:

SELECT
    USER_ID,
    SUM(CASE WHEN RESULT = '胜' THEN 1 END) WIN,
    SUM(CASE WHEN RESULT = '负' THEN 1 END) FAIL
FROM B
GROUP BY USER_ID

完整的SQL:

SELECT
  A.NAME AS '姓名',
  WIN AS '胜',
  FAIL AS '负'
FROM A
  LEFT JOIN (
              SELECT
                USER_ID,
                SUM(CASE WHEN RESULT = '胜' THEN 1 END) WIN,
                SUM(CASE WHEN RESULT = '负' THEN 1 END) FAIL
              FROM B
              GROUP BY USER_ID) B_RESULT
  ON A.USER_ID = B_RESULT.USER_ID;

总结: 解法一的需要CASE WHEN语法和GROUP BY,其实就是一个行转列的体现。


解法二:同解法一,可以通过GROUP BY分组的形式生成中间表,SQL如下:

SELECT USER_ID,RESULT,COUNT(1) NUM  FROM B GROUP BY USER_ID,RESULT;

中间表如下:

user_idresultnum
10002
10001
10011
10011

接下来需要行转列:

SELECT
  USER_ID,
  SUM(CASE WHEN RESULT = '胜' THEN NUM END) WIN,
  SUM(CASE WHEN RESULT = '负' THEN NUM END) FAIL
FROM(
  SELECT USER_ID,RESULT,COUNT(1) NUM
  FROM B GROUP BY USER_ID,RESULT)B_TEMP GROUP BY USER_ID;

行转列的结果:

user_idwinfail
100021
100111

再关联表A即可:

SELECT NAME,WIN,FAIL FROM A LEFT JOIN (
  SELECT
      USER_ID,
      SUM(CASE WHEN RESULT = '胜'THEN NUM END) WIN,
      SUM(CASE WHEN RESULT = '负'THEN NUM END) FAIL
   FROM (
          SELECT USER_ID, RESULT,COUNT(1) NUM FROM B GROUP BY USER_ID, RESULT 
    ) B_TEMP
   GROUP BY USER_ID) B_RESULT ON A.USER_ID = B_RESULT.USER_ID

本文基于Centos 7.2 jdk1.8.0_161apache-tomcat-8.0.52solr-6.6.3

Solr界面介绍

Solr后台地址:http://127.0.0.1:8080/solr/index.html

solr_dashboard.jpg

Dashboard仪表盘:Solr版本信息、JVM、JVM-Memory 等

Logging:Solr运行日志

Core Admin索引库管理:包括创建coreAdd Core、卸载Core Unload、重新加载配置文件reload、优化Optimize

Core SelectorCore核心选择器:概况Overview、分词Analysis、查询Query、数据导入Dataimport

Core Selector的内容在后面再做详细介绍,这里只做简单的认知。

创建Solr Core

Solr home的路径为/opt/solr_home

mkdir -p test/conf

- 阅读剩余部分 -

     Java提供了一种序列化机制,可以将一个对象的类型和数据等信息写入到文件(序列化作用于对象),这个机制就是序列化机制。之后可以通过反序列化机制将其读取出来并用其新建对象,该过程基于JVM,因此可以在一个平台上序列化之后在另一平台上反序列化出对象。有时候因业务需要(如银行卡号、密码等敏感信息)并不会将所有的信息都序列化,这时需要使用transient关键字标识该属性不会序列化到文件中。

User类:实现了Seriazable

一个类要被序列化必须满足2个条件:

1、该类必须实现 java.io.Serializable对象:ArrayList、HashMap都实现了都可以被序列化

2、该类的所有属性都可以被序列化,如果不可被序列化则该属性必须用transient注明是短暂的

import java.io.Serializable;
/**
 * Created by m@zhangguoli.cn on 07-11-011 <br >
 */
public class User implements Serializable {

    public String uuid;
    public String username;
    public transient String password;
}

序列化

Java序列化后生成的文件后缀为.ser

- 阅读剩余部分 -

Solr官网:http://lucene.apache.org/solr/

0、环境及各文件下载地址

1、 CentOS 6.5 X64

2、 jdk-8u161-linux-x64.tar.gz

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
https://dn-zhangguoli.qbox.me/solr/jdk-8u161-linux-x64.tar.gz

3、 apache-tomcat-8.0.52.tar.gz

https://archive.apache.org/dist/tomcat/tomcat-8/
https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.52/bin/apache-tomcat-8.0.52.tar.gz

4、 solr-6.6.3.tgz

http://lucene.apache.org/solr/downloads.html
https://dn-zhangguoli.qbox.me/solr/solr-6.6.3.tgz

1、JDK安装及配置

参考 CentOS6.5 安装JDK 、Tomcat

2、Solr环境搭建及配置

1、解压apache-tomcat-8.0.52.tar.gzsolr-6.6.3.tgz

- 阅读剩余部分 -

学习JDK的动态代理前需要了解静态代理的实现,假设我们有一个接口Moveable,一个类BMW,通过静态代理的方式获取汽车行驶的时间。

一、静态代理

(1)Moveable接口,有个move()方法

package guoli.proxy;

/**
 * @author zhangguoli.cn
 * @date 2018/2/9
 */
public interface Moveable {
    void move();
}

(2)类BMW实现了Moveable接口

- 阅读剩余部分 -

java.sql下的StatementPreparedStatementCallableStatement是用来执行SQL查询的API。其中Statement用于执行普通查询,PreparedStatement用于执行参数化查询,CallableStatement则用于存储过程。他们之间的继承关系:PreparedStatement extends StatementCallableStatement extends PreparedStatement

本文主要介绍的是PreparedStatement的简单使用、相比Statement的优势,以及PreparedStatement的局限性。

PreparedStatement示例

String url = "jdbc:mysql://127.0.0.1:3306/dbname";
//获取一个连接
Connection conn = DriverManager.getConnection(url, "username", "password");
//PreparedStatement 为预编译对象
PreparedStatement pst = conn.prepareStatement("select uuid from test limit ?");
pst.setInt(1, 1);
//结果对象
ResultSet result = pst.executeQuery();
while (result.next()) {
    System.out.println(result.getString("uuid"));
}
//依次关闭
result.close();
pst.close();
connection.close();

PreparedStatement优势

- 阅读剩余部分 -

本文基于:CentOS release 6.5 (Final)

注意SMTP使用默认端口25和加密端口465在配置上的区别

安装

yum -y install mailx

配置发送人信息

vim /etc/mail.rc 在最后增加:

set from=yourEmailAddress
set smtp=smtpAddress
set smtp-auth-user=yourEmailAddress
set smtp-auth-password=youPassword
set smtp-auth=login

使用三种方式发送邮件

  • 命令行: mail -s "theme" addressee,回车后输入内容按Ctrl+D发送邮件.
  • 管道符: echo "mail main content" | mail -s "theme" addressee
  • 文件内容作为邮件内容: mail -s "theme" addressee < /tmp/t.txt

thme是邮件标题,addressee收件人地址


在搜索CentOS上发送邮件时,大部分都是上面的流程,的确在部分机器是测试成功的,唯独ECS不成功,后来了解到ECS默认关闭25端口。


使用SSL的方式发送邮件

- 阅读剩余部分 -

需求:自动备份网站数据文件到七牛

    os      : CentOS release 6.5 (Final)
    website : /opt/website
    MySQL   : /opt/mysql
    backup  : /opt/backup
    qshell  : /opt/qshell

备份网站文件

vim /opt/website.sh

#!/bin/sh
# tar /opt/website to /opt/backup/website

mkdir -p /opt/backup/website
t=`date +"%Y%m%d_%H%M%s"`
tar -zcvf /opt/backup/website/$t.tar.gz /opt/website

chmod u+x website.sh

备份MySQL文件

- 阅读剩余部分 -

OAuth2.0是一个开放授权(open authorization)标准,允许用户让第三方应用获取其在其他网站的授权码,而无需提供给第三方应用在某网站的账号与密码。

OAuth2.0授权流程

假设第三方应用为zhangguoli.cn,服务器提供商为example.com/,授权服务器、认证服务器和资源服务器可以是一个服务器。

- 阅读剩余部分 -

CentOS release 6.5 (Final)
Oracle Release 11.2.0.4.0

  • 使用ssh连接到服务器
  • 切换到Oracle用户: su - oracle
  • 连接到Oracle:sqlplus /nolog
  • 使用管理员身份登录数据库: conn sys/sys as dba
  • 修改密码:ALTER USER user_name IDENTIFIED BY new_password;