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;
}
}
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、编写代码, 实现创建线程的五种写法
- 继承 Thread, 重写 run
- 实现 Runnable, 重写 run
- 继承 Thread, 重写 run, 使用匿名内部类
- 实现 Runnable, 重写 run, 使用匿名内部类
- 使用 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、编写代码, 实现多线程数组求和.
- 给定一个很长的数组 (长度 1000w), 通过随机数的方式生成 1-100 之间的整数.
- 实现代码, 能够创建两个线程, 对这个数组的所有元素求和.
- 其中线程1 计算偶数下标元素的和, 线程2 计算奇数下标元素的和.
- 最终再汇总两个和, 进行相加
- 记录程序的执行时间.
/**
* 题目名称 :
* 编写代码, 实现多线程数组求和.
* 题目内容 :
* 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的区别
从方法的区别,及运行结果的区别分别说明
作用功能不同:
- run方法的作用是描述线程具体要执行的任务;
- start方法的作用是真正的去申请系统线程
运行结果不同:
- run方法是一个类中的普通方法,主动调用和调用普通方法一样,会顺序执行一次;
- start调用方法后, start方法内部会调用Java 本地方法(封装了对系统底层的调用)真正的启动线程,并执行run方法中的代码,run 方法执行完成后线程进入销毁阶段。
33、
34、
35、
36、
37、
38、
39、
40、
41、
42、
43、
44、
45、
46、
47、
48、
49、
50、