Java---刷题03

1、136. 只出现一次的数字 - 力扣(LeetCode)

2、138. 复制带随机指针的链表 - 力扣(LeetCode)

3、实现哈希表代码, 使用哈希桶方式解决哈希冲突

public class HashBucket {
    private static class Node {
        private int key;
        private int value;
        Node next;
 
        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }
 
    private Node[]  array;
    private int size;   // 当前的数据个数
	private static final double LOAD_FACTOR = 0.75;
    private static final int DEFAULT_SIZE = 8;//默认桶的大小
	
	public HashBucket() {
        array = new Node[DEFAULT_SIZE ];
        size = 0;
    }
 
    public int put(int key, int value) {
        // key => int
        // int 合法的下标
        int index = key % array.length;
 
        // 2. 在链表中查找 key 所在的结点    长度一般是固定的 所以认为这里也是O(1)
        //      如果找到了,更新
        //      所有结点都不是 key,插入一个新的结点
        for (Node cur = array[index]; cur != null; cur = cur.next) {
            if (key == cur.key) {
                int oldValue = cur.value;
                cur.value = value;
                return oldValue;
            }
        }
		//头插法
        Node node = new Node(key, value);
        node.next = array[index];
        array[index] = node;
        size++;
 
        if (loadFactor() >= LOAD_FACTOR ) {
            resize();
        }
 
        return -1;
    }
	
	private double loadFactor() {
        return size * 1.0 / array.length;
    }
 
    private void resize() {
        Node[] newArray = new Node[array.length * 2];
        for (int i = 0; i < array.length; i++) {
            Node next;
            for (Node cur = array[i]; cur != null; cur = next) {
                next = cur.next;
				//每个节点都要进行重新计算index
                int index = cur.key % newArray.length;
				//头插法  第一次插入的时候newArray[index]为空
                cur.next = newArray[index];
                newArray[index] = cur;
            }
        }
        array = newArray;
    }
	
	public int get(int key) {
        // 1. key =》 int 类型
        // 2. 保证下标是合法的
        int index = key % array.length;
 
        Node head = array[index];
        for (Node cur = head; cur != null; cur = cur.next) {
            if (key == cur.key) {
                return cur.value;
            }
        }
 
        return -1;
    }
}
  
 

4、217. 存在重复元素 - 力扣(LeetCode)

5、219. 存在重复元素 II - 力扣(LeetCode)

6、设计一张商品表,包含以下字段:商品名称、商品价格、商品库存、商品描述

drop table if exists product;
create table product(
	name varchar(20),
	price decimal(11,2),
	storage int,
	description varchar(100)
);

7、设计一张老师表,包含以下字段:姓名、年龄、身高、体重、性别、学历、生日、身份证号

drop table if exists teacher;
create table teacher(
	name varchar(20),
	age int,
	height double,
	weight double,
	sex bit,
	birthday TIMESTAMP,
	id_number varchar(18)
);

8、设计一张图书表,包含以下字段:图书名称,图书作者、图书价格、图书分类

drop table if exists book;
create table book(
	name varchar(20),
	author varchar(20),
	price decimal(11,2),
	category varchar(20)
);

9、在图书表中新增一条记录:Java核心技术、作者“Cay S. Horstman”,价格56.43,分类为“计算机技术”

insert into book values('Java核心技术','Cay S.Horstman',56.43,'计算机技术');

 全列都有值,直接全列插入就行了。

10、在以上创建的商品表中插入一条数据:名称为“学生书包”、价格18.91、库存101、描述为空

insert into product(name,price,storage) values('学生书包',18.91,101);

可以全列插入,也可以直插需要的三列。全列插入就是写成('学生书包',18.91,101, null)。 

11、student学生表中,字段有姓名name,年龄age,要求查询姓张,并且年龄在18到25岁之间的学生

select * from student where name like '张%' and age between 18 and 25;

姓张那么就是like '张%',年龄要某个区间内,用between...and...即可

12、查询article文章表中,发表日期create_date在2019年1月1日上午10点30分至2019年11月10日下午4点2分的文章

select * from article where create_date between '2019-01-01 10:30:00' and '2019-11-10 16:02:00';

时间信息也是可以用between...and...的。

13、查询article文章表中,文章标题title为空,或者满足发表日期create_date在2019年1月1日之后

select * from article where title is null or create_date > '2019-01-01 00:00:00';

判空可以用is null或者<=> null,发表日期可以直接用大于号比较。

14、查询book图书表中,作者author列不为空,或者满足条件:价格price在50元以上且出版日期publish_date在2019年之后的图书信息

select * from book where author is not null or (price >50 and publish_date>'2019-01-01 00:00:00');

不为空用is not null或者not ... <=> null。这个条件跟后面是或关系,后两个是且关系。

15、查询用户user表中,满足以下条件的用户数据:

1. ID在1至200或300至500,且账号accout列不为空

2. 充值金额amount在1000以上。

select * from user where (id between 1 and 200 or id between 300 and 500) and accout is not null or amount>1000;

条件1两个between...and...间是或关系,跟“accout列不为空”这个条件是且关系。条件1与条件2间是或关系。

16、修改“Java核心技术”的图书信息,将价格修改为61

update book set price=61 where name='Java核心技术';

17、删除商品表中,价格大于60,或者是库存小于200的记录

delete from product where price>60 or storage<200;

18、修改所有库存大于30的商品记录,将价格增加50块

update product set price=price+50 where storage>30;

19、设计一个考勤系统

考勤系统,包含员工表,考勤记录表

-- 主要考虑记录表中的记录信息,是如何关联到员工表,员工与记录关系为1:m。

create table emp(
id int primary key,
  name varchar(20)
);
create table info(
id int primary key,
  emp_id int,
  info_date timestamp,
  foreign key (emp_id) references emp(id)
);

20、设计一个学校宿舍管理系统 

学校宿舍管理系统,要求包含宿舍信息,学生信息,每日的宿舍查房记录。

-- 主要考虑学生与宿舍的关系:m:1,宿舍的查房记录是根据宿舍来查的,与宿舍有关系,一个宿舍可以多次查房,宿舍与查房记录是1:m的关系

create table dormitory(
id int primary key,
  number varchar(20)
);

create table student(
id int primary key,
  name varchar(20),
  dormitory_id int,
  foreign key (dormitory_id) references dormitory(id)
);


create table info(
id int primary key,
  dormitory_id int,
  status bit,
  info_date timestamp,
  foreign key (dormitory_id) references dormitory(id)

);

21、设计一个车辆违章系统

车辆违章系统,包含用户表,车辆表,违章信息表。违章信息表中包含用户和车辆的违章信息

 -- 用户可以拥有多辆车,关系为1:m,题目已经说明违章信息包括用户和车辆,说明违章信息表中要记录用户和车辆,一个用户可以有多次违章记录,用户与违章记录关系为1:m,一辆车也可以有多次违章记录,车辆与违章记录关系也为1:m

create table user(
id int primary key,
  name varchar(20)
);
create table cars(
id int primary key,
  name varchar(20),
  user_id int,
  foreign key (user_id) references user(id)
);

create table info(
id int primary key,
  user_id int,
  cars_id int,
  foreign key (user_id) references user(id),
  foreign key (cars_id) references cars(id)
);

22、设计一个学校食堂管理系统 

学校食堂管理系统,包含食堂表,食堂仓口表,仓口收费记录表

-- 一个食堂有多个仓口卖饭,关系为1:m,每个仓口卖饭可以有很多次,仓口与收费记录也是1:m

create table hall(
id int primary key,
  name varchar(20)
);
create table hall_opening(
id int primary key,
  name varchar(20),
  hall_id int,
  foreign key (hall_id) references hall(id)
);
create table info(
id int primary key,
  price int,
  info_date timestamp,
  hall_opening_id int,
  foreign key (hall_opening_id) references hall_opening(id)
);

23、有一张员工表emp,字段:姓名name,性别sex,部门depart,工资salary。查询以下数据:

1、查询男女员工的平均工资

2、查询各部门的总薪水

3、查询总薪水排名第二的部门

4、查询姓名重复的员工信息

5、查询各部门薪水大于10000的男性员工的平均薪水

1:select sex,avg(salary) from emp group by sex;

说明:平均值使用聚合函数avg,并且按照性别男女分组,group by 性别字段

2:select depart,sum(salary) from emp group by depart;

说明:总薪水使用聚合函数sum取薪水字段求和,并且按照部门字段分组,group by 部门字段

3:select depart,sum(salary) from emp group by depart order by sum(salary) desc limit 1,1;

说明:order by语句先按照总薪水排序,之后取第二条数据,可以使用分页,每一页1条数据,第二页就是该结果

4:select name from emp group by name having count(name)>1;

说明:名字重复,说明同一个名字有多条数据,可以先按照名字分组,分组之后再过滤行数大于1的,就表示同一个名字至少有2条记录,重复了

5:select depart,avg(salary) from emp where salary>10000 and sex='男' group by depart;

说明:这里需要注意题目要求是查询薪水大于10000的男性员工,这个是在按部门分组前就过滤,在过滤后的结果集中再查询各个部门的平均薪水

24、写出以下数据库的查询条件【交大思诺2020届校招笔试题】

有两个表分别如下:

表A(varchar(32) name, int grade)

数据:zhangshan 80, lisi 60, wangwu 84

表B(varchar(32) name, int age)

数据:zhangshan 26, lisi 24, wangwu 26, wutian 26

写SQL语句得到如下查询结果:

| NAME   | GRADE | AGE |

| --------- | ----- | ---- |

| zhangshan | 80  | 26  |

| lisi   | 60  | 24  |

| wangwu  | 84  | 26  |

| wutian  | null | 26  |

SELECT
B.NAME,
A.grade,
B.age 
FROM
B left join A
ON
A.NAME = B.NAME

 说明:主要考察使用关联查询时需要使用内联还是外联,这里wutian再A表中没有记录,但还是需要返回结果,所以应该将B表作为外表进行外连接查询

25、有员工表、部门表和薪资表,根据查询条件写出对应的sql【同程艺龙2020届校招笔试题】

现在有员工表、部门表和薪资表。部门表depart的字段有depart_id, name;员工表 staff 的字段有 staff_id, name, age, depart_id;薪资表salary 的字段有 salary_id,staff_id,salary,month。

(问题a):求每个部门'2016-09'月份的部门薪水总额

(问题b):求每个部门的部门人数,要求输出部门名称和人数

(问题c):求公司每个部门的月支出薪资数,要求输出月份和本月薪资总数

(问题a):求每个部门'2016-09'月份的部门薪水总额

SELECT
dep.NAME,
sum( sal.salary ) 
FROM
salary sal
JOIN staff sta ON sal.staff_id = sta.staff_id
JOIN depart dep ON sta.depart_id = dep.depart_id 
WHERE
YEAR ( sal.MONTH ) = 2016 
AND MONTH ( sal.MONTH ) = 9 
GROUP BY
dep.depart_id

说明:
mysql中年和月的函数分别是year(字段),month(字段)
查询要求的是每个部门的信息,所以要按照部门进行分组,部门和员工为1:m,员工与薪水为1:m,查询要求有部门,有薪水,所以必须关联3张表查询

(问题b):求每个部门的部门人数,要求输出部门名称和人数

SELECT
dep.NAME,
count( sta.staff_id ) 
FROM
staff sta
JOIN depart dep ON dep.depart_id = sta.depart_id 
GROUP BY
sta.depart_id

说明:查询要求的信息有部门,有人数,人数只能从员工表中获取,所以关联表为部门表/员工表。按照部门id分组查询员工id的行数

(问题c):求公司每个部门的月支出薪资数,要求输出月份和本月薪资总数

SELECT
dep.NAME,
sal.MONTH,
sum( sal.salary ) 
FROM
depart dep
JOIN staff sta ON dep.depart_id = sta.depart_id
JOIN salary sal ON sta.staff_id = sal.staff_id 
GROUP BY
dep.depart_id,
sal.MONTH

说明:按照题目要求,查询信息有部门/月/每个部门每月薪资总额,其中薪水信息再薪水表中,每个员工可以有多条薪资记录(不同时间)。所以需要按照部门分组,再按照月份分组,查询分组的部门在不同月份下的总薪水

26、编写一个SQL查询,获取Employee表中第二高的薪水(Salary)

+-----+-------+

| Id | Salary|

+-----+-------+

| 1  | 100 |

+-----+-------+

| 2  | 200 |

+-----+-------+

| 3  | 300 |

+-----+-------+

例如上述Employee表,SQL查询应该返回200作为第二高的薪水。如果不存在第二高的薪水,那么查询应该返回null。

+---------------------+

| SecondHighestSalary |

+---------------------+

|    200     |

+---------------------+

select ifnull((select Salary from Employee order by Salary desc limit 1,1),null ) as SecondHighestSalary;

 说明:先查询最高的薪水,然后适用ifnull,如果没有就返回null

27、使用UNION语句查询

已知T1和T2的字段定义完全相同,T1有5条不同数据,T2有5条不同数据,其中T1有2条数据存在表T2中,使用UNION语句查询这些数据,要求重复数据不出现

SELECT * FROM T1 UNION SELECT * FROM T2

说明:union不能出现重复,union all会出现重复数据。根据题目要求使用union

28、有一个图书管理系统,请根据要求写出对应的sql

有一个图书管理系统,包含学生和图书信息,且图书可以进行分类,学生可以在一个时间范围内借阅图书,并在这个时间范围内归还图书。表和表关系如下:

DROP DATABASE IF EXISTS ebook;

CREATE DATABASE ebook CHARACTER SET 'utf8mb4';

USE ebook;

-- ----------------------------

-- Table structure for category

-- ----------------------------

DROP TABLE IF EXISTS category;

CREATE TABLE category (

 id int(11) PRIMARY KEY AUTO_INCREMENT,

 name varchar(20)

);

-- ----------------------------

-- Records of category

-- ----------------------------

INSERT INTO category VALUES (1, '历史');

INSERT INTO category VALUES (2, '艺术');

INSERT INTO category VALUES (3, '计算机');

INSERT INTO category VALUES (4, '数学');

INSERT INTO category VALUES (5, '小说');

-- ----------------------------

-- Table structure for student

-- ----------------------------

DROP TABLE IF EXISTS student;

CREATE TABLE student (

 id int(11) PRIMARY KEY AUTO_INCREMENT,

 name varchar(20)

);

-- ----------------------------

-- Records of student

-- ----------------------------

INSERT INTO student VALUES (1, '王昭君');

INSERT INTO student VALUES (2, '李白');

INSERT INTO student VALUES (3, '貂蝉');

INSERT INTO student VALUES (4, '小乔');

INSERT INTO student VALUES (5, '韩信');

-- ----------------------------

-- Table structure for book

-- ----------------------------

DROP TABLE IF EXISTS book;

CREATE TABLE book (

 id int(11) PRIMARY KEY AUTO_INCREMENT,

 name varchar(20),

 author varchar(20),

 price decimal(10, 2),

 category_id int(11),

 CONSTRAINT fk_book_category_id FOREIGN KEY (category_id) REFERENCES category (id)

);

-- ----------------------------

-- Records of book

-- ----------------------------

INSERT INTO book VALUES (1, '深入理解Java虚拟机', '周志明', 57.90, 3);

INSERT INTO book VALUES (2, '西游记', '吴承恩', 30.68, 5);

INSERT INTO book VALUES (3, '儒林外史', '吴敬梓', 18.80, 5);

INSERT INTO book VALUES (4, '聊斋志异', '蒲松龄', 21.00, 5);

INSERT INTO book VALUES (5, '史记', '司马迁', 278.20, 1);

INSERT INTO book VALUES (6, '资治通鉴', '司马光', 524.00, 1);

INSERT INTO book VALUES (7, 'Java核心技术 卷I:基础知识', 'Cay S. Horstmann', 92.50, 3);

INSERT INTO book VALUES (8, 'Java核心技术卷II:高级特性', 'Cay S. Horstmann', 111.20, 3);

INSERT INTO book VALUES (9, 'Java多线程编程核心技术', '高洪岩', 47.50, 3);

INSERT INTO book VALUES (10, '诗经', '孔子', 22.00, 2);

INSERT INTO book VALUES (11, '唐诗三百首', '蘅塘居士', 49.30, 2);

INSERT INTO book VALUES (12, '唐诗三百首', '蘅塘居士', 55.00, 2);

INSERT INTO book VALUES (13, '西游记', '吴承恩', 47.50, 5);

INSERT INTO book VALUES (14, '唐诗三百首', '蘅塘居士', 56.50, 2);

-- ----------------------------

-- Table structure for borrow_info

-- ----------------------------

DROP TABLE IF EXISTS borrow_info;

CREATE TABLE borrow_info (

 id int(11) PRIMARY KEY AUTO_INCREMENT,

 book_id int(11),

 student_id int(11),

 start_time timestamp null,

 end_time timestamp null,

 CONSTRAINT fk_borrow_info_book_id FOREIGN KEY (book_id) REFERENCES book (id),

 CONSTRAINT fk_borrow_info_student_id FOREIGN KEY (student_id) REFERENCES student (id)

);

-- ----------------------------

-- Records of borrow_info

-- ----------------------------

INSERT INTO borrow_info VALUES (1, 1, 1, '2018-11-07 18:50:43', '2018-12-07 18:51:01');

INSERT INTO borrow_info VALUES (2, 7, 1, '2019-07-10 10:21:00', '2019-09-10 10:21:00');

INSERT INTO borrow_info VALUES (3, 8, 1, '2019-09-10 10:21:00', '2019-10-10 10:21:00');

INSERT INTO borrow_info VALUES (4, 2, 2, '2019-03-02 16:37:00', '2019-04-02 16:37:00');

INSERT INTO borrow_info VALUES (5, 4, 2, '2019-03-12 14:25:00', '2019-04-12 14:25:00');

INSERT INTO borrow_info VALUES (6, 10, 2, '2019-07-13 16:21:00', '2019-10-13 16:21:00');

INSERT INTO borrow_info VALUES (7, 11, 2, '2019-06-09 09:40:00', '2019-07-09 09:40:00');

INSERT INTO borrow_info VALUES (8, 13, 2, '2019-01-03 15:11:00', '2019-04-03 15:11:00');

INSERT INTO borrow_info VALUES (9, 7, 3, '2019-05-15 13:13:00', '2019-06-15 13:13:00');

INSERT INTO borrow_info VALUES (10, 8, 3, '2019-04-27 13:53:00', '2019-05-27 13:53:00');

INSERT INTO borrow_info VALUES (11, 9, 3, '2019-06-01 11:32:00', '2019-07-01 11:32:00');

INSERT INTO borrow_info VALUES (12, 3, 4, '2019-07-01 09:40:00', '2019-08-01 09:40:00');

INSERT INTO borrow_info VALUES (13, 4, 4, '2019-06-19 11:40:00', '2019-07-19 11:40:00');

INSERT INTO borrow_info VALUES (14, 5, 4, '2019-06-25 09:23:00', '2019-09-25 09:23:00');

INSERT INTO borrow_info VALUES (15, 10, 4, '2019-08-27 15:30:00', '2019-09-27 15:30:00');

INSERT INTO borrow_info VALUES (16, 5, 5, '2019-01-23 14:20:00', '2019-04-23 14:20:00');

INSERT INTO borrow_info VALUES (17, 6, 5, '2019-03-09 10:45:00', '2019-04-09 10:45:00');

INSERT INTO borrow_info VALUES (18, 10, 5, '2019-06-17 11:32:00', '2019-09-17 11:32:00');

要求:

1. 新增貂蝉同学的借阅记录:诗经,从2019年9月25日17:50到2019年10月25日17:50

2. 查询计算机分类下的图书借阅信息

3. 修改图书《深入理解Java虚拟机》的价格为61.20

4. 删除id最大的一条借阅记录

 1. 新增貂蝉同学的借阅记录:诗经,从2019年9月25日17:50到2019年10月25日17:50

首先创建数据库JDBC工具类

package com.bit.util;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Util {
//使用连接池
  private static final DataSource DATA_SOURCE    = new MysqlDataSource();
  static {
    ((MysqlDataSource) DATA_SOURCE).setUrl("jdbc:mysql://localhost:3306/book");
    ((MysqlDataSource) DATA_SOURCE).setUser("root");
    ((MysqlDataSource) DATA_SOURCE).setPassword("root");
  }
  public static void main(String[] args) {
    System.out.println(getConnection());
  }
// 获取数据库连接
  public static Connection getConnection(){
    try {
      return DATA_SOURCE.getConnection();
    } catch (SQLException e) {
      throw new RuntimeException("获取数据库连接失败", e);
    }
  }
// 释放资源
  public static void close(ResultSet resultSet, Statement statement,
               Connection connection){
      try {
        if(resultSet != null) {
          resultSet.close();
        }
       if(statement != null){
          statement.close();
        }
        if(connection != null){
          connection.close();
        }
      } catch (SQLException e) {
       throw new RuntimeException("数据库操作异常", e);
      }
  }

//日期字符串转Java日期类Date和sql时间戳Timestamp
  public static Timestamp getTimestamp(String dateString){
    try {
     // 年-月-日 小时:分钟:秒
      java.util.Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateString);
      return new java.sql.Timestamp(date.getTime());
    } catch (ParseException e) {
     throw new RuntimeException("日期格式化错误:"+dateString, e);
    }
  }
}
package com.bit.book;
import com.bit.util.Utill
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class AddBorrow {
  /**
   * 新增貂蝉同学的借阅记录:诗经,从2019年9月25日17:50到2019年10月25日17:50
   */
  public static void main(String[] args) {
   //1.创建数据库连接对象
    Connection connection = null;
    //2.创建操作命令对象
    PreparedStatement preparedStatement = null;
    try {
      connection = Util.getConnection();
      String sql = "insert into borrow_info(book_id, student_id," +
          " start_time, end_time) select b.id,s.id,?,?" +
          " from book b,student s where b.name=? and s.name=?";
      preparedStatement = connection.prepareStatement(sql);
      preparedStatement.setTimestamp(1, Util.getTimestamp("2019-09-25 17:50:00"));
      preparedStatement.setTimestamp(2, Util.getTimestamp("2019-10-25 17:50:00"));
      preparedStatement.setString(3, "诗经");
      preparedStatement.setString(4, "貂蝉");
      System.out.println(preparedStatement);
      //3.执行sql
      int result = preparedStatement.executeUpdate();
      System.out.println(result);
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
     //4.释放资源
      Util.close(null, preparedStatement, connection);
    }
  }
}

2. 查询计算机分类下的图书借阅信息

package com.bit.book;
import com.bit.util.Util;
import java.sql.*;
public class QueryBorrow {
  /**
   * 查询计算机分类下的图书借阅信息
   * @param args
   */
  public static void main(String[] args) {
    Connection    connection    = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
      connection = Util.getConnection();
      String sql = "SELECT bk.NAME book_name,bk.author book_author," +
          "s.NAME student_name,bi.start_time,bi.end_time" +
          " FROM borrow_info bi JOIN book bk ON bi.book_id = bk.id" +
          " JOIN category c ON bk.category_id = c.id" +
          " JOIN student s ON bi.student_id = s.id" +
          " WHERE c.NAME = ?";
      preparedStatement = connection.prepareStatement(sql);
      preparedStatement.setString(1, "计算机");
      resultSet = preparedStatement.executeQuery();
      while(resultSet.next()){
        String  bookName  = resultSet.getString("book_name");
        String  bookAuthor = resultSet.getString("book_author");
        String  studentName = resultSet.getString("student_name");
        Timestamp startTime  = resultSet.getTimestamp("start_time");
        Timestamp  endTime   = resultSet.getTimestamp("end_time");
        System.out.println(String.format("书名:%s,作者:%s,借阅者:%s," +
            "借阅起始日期:%s,结束日期:%s",
            bookName, bookAuthor, studentName, startTime, endTime));
      }
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      Util.close(resultSet, preparedStatement, connection);
    }
  }
}

3. 修改图书《深入理解Java虚拟机》的价格为61.20

package com.bit.book;



import com.bit.util.Util;



import java.math.BigDecimal;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;



public class UpdateBook {



  /**

   * 修改图书《深入理解Java虚拟机》的价格为61.20

   */

  public static void main(String[] args) {

    Connection    connection    = null;

    PreparedStatement preparedStatement = null;

    try {

      connection = Util.getConnection();

      String sql = "update book set price=? where name =?";

      preparedStatement = connection.prepareStatement(sql);

      preparedStatement.setBigDecimal(1, new BigDecimal("61.20"));

      preparedStatement.setString(2, "深入理解Java虚拟机");

      System.out.println(preparedStatement);

      int result = preparedStatement.executeUpdate();

      System.out.println(result);

    } catch (SQLException e) {

      e.printStackTrace();

    } finally {

      Util.close(null, preparedStatement, connection);

    }

  }

}

4. 删除id最大的一条借阅记录

package com.bit.book;



import com.bit.util.Util;



import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;



public class DeleteBorrow {



  /**

   * 删除id最大的一条借阅记录

   */

  public static void main(String[] args) {

    Connection    connection    = null;

    PreparedStatement preparedStatement = null;

    try {

      connection = Util.getConnection();

      String sql = "delete from borrow_info where id =" +

          "(select r.id from (select max(id) id from borrow_info) r)";

      preparedStatement = connection.prepareStatement(sql);

      int result = preparedStatement.executeUpdate();

      System.out.println(result);

    } catch (SQLException e) {

      e.printStackTrace();

    } finally {

      Util.close(null, preparedStatement, connection);

    }

  }

}

29、编写代码, 实现创建线程的五种写法

  1. 继承 Thread, 重写 run
  2. 实现 Runnable, 重写 run
  3. 继承 Thread, 重写 run, 使用匿名内部类
  4. 实现 Runnable, 重写 run, 使用匿名内部类
  5. 使用 lambda 表达式

通过继承Thread类并实现run方法创建一个线程

// 定义一个Thread类,相当于一个线程的模板
class MyThread01 extends Thread {
    // 重写run方法// run方法描述的是线程要执行的具体任务@Overridepublic void run() {
        System.out.println("hello, thread.");
    }
}
 
/**
 * 继承Thread类并重写run方法创建一个线程
 * @author  比特就业课
 * @created 2022-06-20
 */
public class Thread_demo01 {
    public static void main(String[] args) {
        // 实例化一个线程对象
        MyThread01 t = new MyThread01();
        // 真正的去申请系统线程,参与CPU调度
        t.start();
    }
}

通过实现Runnable接口,并实现run方法的方法创建一个线程

// 创建一个Runnable的实现类,并实现run方法
// Runnable主要描述的是线程的任务
class MyRunnable01 implements Runnable {
    @Overridepublic void run() {
        System.out.println("hello, thread.");
    }
}
/**
 * 通过继承Runnable接口并实现run方法
 * @author  比特就业课
 * @created 2022-06-20
 */
public class Thread_demo02 {
    public static void main(String[] args) {
        // 实例化Runnable对象
        MyRunnable01 runnable01 = new MyRunnable01();
        // 实例化线程对象并绑定任务
        Thread t = new Thread(runnable01);
        // 真正的去申请系统线程参与CPU调度
        t.start();
    }
}

通过Thread匿名内部类创建一个线程

/**
 * 通过Thread匿名内部类的方法创建一个线程
 * @author 比特就业课
 * @created 2022-06-20
 */
public class Thread_demo03 {public static void main(String[] args) {
        Thread t = new Thread(){
            // 指定线程任务
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        };
        // 真正的申请系统线程参与CPU调度
        t.start();
    }
}

通过Runnable匿名内部类创建一个线程

/**
 * 通过Runnable匿名内部类创建一个线程
 * @author 比特就业课
 * @created 2022-06-20
 */
public class Thread_demo04 {public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            // 指定线程的任务
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());                
            }
        });
        // 申请系统线程参与CPU调度
        t.start();
    }
}

通过Lambda表达式的方式创建一个线程

/**
 * 通过Lambda表达式的方式创建一个线程
 * @author 比特就业课
 * @created 2022-06-20
 */
public class Thread_demo05 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            // 指定任务:任务是循环打印当前线程名
            while (true) {
                System.out.println(Thread.currentThread().getName());
                try {
                    // 休眠1000ms
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        // 申请系统线程参与CPU调度
        t.start();
    }
}

30、编写代码, 实现多线程数组求和.

  1. 给定一个很长的数组 (长度 1000w), 通过随机数的方式生成 1-100 之间的整数.
  2. 实现代码, 能够创建两个线程, 对这个数组的所有元素求和.
  3. 其中线程1 计算偶数下标元素的和, 线程2 计算奇数下标元素的和.
  4. 最终再汇总两个和, 进行相加
  5. 记录程序的执行时间.

/**
 * 题目名称 :
 * 编写代码, 实现多线程数组求和.
 * 题目内容 :
 * 1. 给定一个很长的数组 (长度 1000w), 通过随机数的方式生成 1-100 之间的整数.
 * 2. 实现代码, 能够创建两个线程, 对这个数组的所有元素求和.
 * 3. 其中线程1 计算偶数下标元素的和, 线程2 计算奇数下标元素的和.
 * 4. 最终再汇总两个和, 进行相加
 * 5. 记录程序的执行时间.
 *
 * @author 比特就业课
 * @created 2022-06-20
 *
 */
public class Thread_2533 {
    public static void main(String[] args) throws InterruptedException {
        // 记录开始时间
        long start = System.currentTimeMillis();
 
        // 1. 给定一个很长的数组 (长度 1000w), 通过随机数的方式生成 1-100 之间的整数.
        int total = 1000_0000;
        int [] arr = new int[total];
        // 构造随机数,填充数组
        Random random = new Random();
        for (int i = 0; i < total; i++) {
            int num = random.nextInt(100) + 1;
            arr[i] = num;
        }
 
 
        // 2. 实现代码, 能够创建两个线程, 对这个数组的所有元素求和.
        // 3. 其中线程1 计算偶数下标元素的和, 线程2 计算奇数下标元素的和.
        // 实例化操作类
        SumOperator operator = new SumOperator();
        // 定义具体的执行线程
        Thread t1 = new Thread(() -> {
            // 遍历数组,累加偶数下标
            for (int i = 0; i < total; i += 2) {
                operator.addEvenSum(arr[i]);
            }
        });
 
        Thread t2 = new Thread(() -> {
            // 遍历数组,累加奇数下标
            for (int i = 1; i < total; i += 2) {
                operator.addOddSum(arr[i]);
            }
        });
 
        // 启动线程
        t1.start();
        t2.start();
        // 等待线程结束
        t1.join();
        t2.join();
 
        // 记录结束时间
        long end = System.currentTimeMillis();
        // 结果
        System.out.println("结算结果为 = " + operator.result());
        System.out.println("总耗时 " + (end - start) + "ms.");
    }
}
 
// 累加操作用这个类来完成
class SumOperator {
    long evenSum;
    long oddSum;
 
    public void addEvenSum (int num) {
        evenSum += num;
    }
 
    public void addOddSum (int num) {
        oddSum += num;
    }
 
    public long result() {
        System.out.println("偶数和:" + evenSum);
        System.out.println("奇数和:" + oddSum);
        return evenSum + oddSum;
    }
}
 
 

31、在子线程执行完毕后再执行主线程代码

有20个线程,需要同时启动。每个线程按0-19的序号打印,如第一个线程需要打印0。请设计代码,在main主线程中,等待所有子线程执行完后,再打印 ok

public static void main(String[] args) throws InterruptedException {
        Thread[] threads = new Thread[20];
        for(int i=0; i<20; i++){
            final int n = i;
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {//内部类使用外部的变量,必须是final修饰
                    System.out.println(n);
                }
            });
        }
        for(Thread t : threads){
            t.start();
        }
        for(Thread t : threads){//同时执行20个线程,再等待所有线程执行完毕
            t.join();
        }
        System.out.println("OK");
    }

 32、请说明Thread类中run和start的区别

从方法的区别,及运行结果的区别分别说明

作用功能不同:

  1. run方法的作用是描述线程具体要执行的任务;
  2. start方法的作用是真正的去申请系统线程

运行结果不同:

  1. run方法是一个类中的普通方法,主动调用和调用普通方法一样,会顺序执行一次;
  2. start调用方法后, start方法内部会调用Java 本地方法(封装了对系统底层的调用)真正的启动线程,并执行run方法中的代码,run 方法执行完成后线程进入销毁阶段。

33、

34、

35、

36、

37、

38、

39、

40、

41、

42、

43、

44、

45、

46、

47、

48、

49、

50、

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值