一、每日一题
21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)
题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:输入:l1 = [], l2 = []
输出:[]
示例 3:输入:l1 = [], l2 = [0]
输出:[0]
提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列
思路:
最开始,判断两个链表是否为空。
首先,定义两个指针,第一个指针通过判断两个链表的表头元素的大小来判断指向,指向值较小的元素,第二个指针等于第一个指针,也指向表头元素的值较小的元素的表。
然后,第二个指针继续向后遍历两个链表。最后必定有一个链表非空,一个链表为空,再把第二个指针指向非空链表的指针目前指向的位置。
代码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(list1==NULL)
{
return list2;
}
if(list2==NULL)
{
return list1;
}
struct ListNode* head;
struct ListNode* tail;
if(list1->val>list2->val)
{
head=list2;
list2=list2->next;
}
else
{
head=list1;
list1=list1->next;
}
tail=head;
while(list1!=NULL&&list2!=NULL)
{
if(list1->val>list2->val)
{
tail->next=list2;
list2=list2->next;
}
else
{
tail->next=list1;
list1=list1->next;
}
tail=tail->next;
}
if(list1!=NULL)
{
tail->next=list1;
}
if(list2!=NULL)
{
tail->next=list2;
}
return head;
}
};
二、学习数据库连接池
昨天学习JDBC,然后实现数据库的增、删、查、改是用到的传统连接机制,虽然简单,但是它使数据库的性能大大降低。
数据库连接池的概念
数据库连接池负责分配、管理和释放数据库,它允许应用程序重复使用一个现有的数据库连接,而不在重复建立新的连接,这就会大大提高数据库操作性能。
1、配置数据集相关配置
public class DbBean {
private String driverName = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
private String userName = "root";
private String password = "root";
private String poolName = "DbBeanPool";// 连接池名字
private int minConnections = 1; // 空闲池,最小连接数
private int maxConnections = 10; // 空闲池,最大连接数
private int initConnections = 5;// 初始化连接数
private long waitTimeOut = 1000;// 重复获得连接的频率
private int maxActiveConnections = 100;// 最大允许的连接数,和数据库对应
private long connectionTimeOut = 1000 * 60 * 20;// 连接超时时间,默认20分钟
public String getDriverName() {
return driverName;
}
public void setDriverName(String driverName) {
this.driverName = driverName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPoolName() {
return poolName;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public int getMinConnections() {
return minConnections;
}
public void setMinConnections(int minConnections) {
this.minConnections = minConnections;
}
public int getMaxConnections() {
return maxConnections;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public int getInitConnections() {
return initConnections;
}
public void setInitConnections(int initConnections) {
this.initConnections = initConnections;
}
public long getConnTimeOut() {
return waitTimeOut;
}
public void setConnTimeOut(long waitTimeOut) {
this.waitTimeOut = waitTimeOut;
}
public int getMaxActiveConnections() {
return maxActiveConnections;
}
public void setMaxActiveConnections(int maxActiveConnections) {
this.maxActiveConnections = maxActiveConnections;
}
public long getConnectionTimeOut() {
return connectionTimeOut;
}
public void setConnectionTimeOut(long connectionTimeOut) {
this.connectionTimeOut = connectionTimeOut;
}
}
2.数据库连接池
/**
*数据库连接池
* 1.初始化连接池
* 根据初始化连接数,创建连接放到空闲池中
* 2.创建获取连接getConnection方法
* 判断是否小于最大活动连接数
* 小于==》判断空闲连接池是否存有连接
* 有==》直接取出放到活动连接池中,然后空闲连接池删除
* 无==》创建新的连接,放到活动连接池中
* 大于==》等待,重试
*/
public class ConnectionPool {
private List<Connection> freeConnection = new Vector<Connection>();
private List<Connection> activeConnection = new Vector<Connection>();
private DbBean dbBean;
private volatile int connNum = 0;
//通过构造函数初始化连接池
public ConnectionPool(DbBean dbBean){
//获取配置文件信息
this.dbBean = dbBean;
//1.初始化连接池
for(int i = 0;i < dbBean.getInitConnections();i++){
Connection connection = newConnect();
if(connection != null){
//放到空闲连接池中
freeConnection.add(connection);
}
}
}
/**
* 2.创建获取连接getConnection方法
* 判断是否小于最大活动连接数
* 小于==》判断空闲连接池是否存有连接
* 有==》直接取出放到活动连接池中,然后空闲连接池删除
* 无==》创建新的连接,放到活动连接池中
* 大于==》等待,重试
* 3.释放连接 回收
* 判断连接是否可用
* ==>判断空闲线程是否已满
* 没满==》回收连接,放到空闲线程池中
* 已满==》关闭连接
* 活动连接池移除该连接
*/
public synchronized Connection getConnection(){
Connection connection = null;
//判断是否小于最大活动连接数
if(connNum <= dbBean.getMaxActiveConnections()){
//判断空闲连接池是否存有连接
if(freeConnection.size() > 0){
//空闲连接池删除
connection = freeConnection.remove(0);
}else {
//创建新的连接
connection = newConnect();
}
//如果连接池可用
if(isAvailable(connection)){
//放到活动连接池中
activeConnection.add(connection);
}else {
//连接已失效
connNum--;
//重复调用
connection = getConnection();
}
}else {
// 大于最大活动连接数,进行等待
try {
wait(dbBean.getConnTimeOut());
} catch (InterruptedException e) {
e.printStackTrace();
}
// 重试
connection = getConnection();
}
return connection;
}
//创建连接
private synchronized Connection newConnect(){
Connection connection = null;
try {
Class.forName(dbBean.getDriverName());
connection = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword());
//记录连接数
connNum++;
} catch (Exception e) {
e.printStackTrace();
}finally {
return connection;
}
}
// 判断连接是否可用
public boolean isAvailable(Connection connection) {
try {
if (connection == null || connection.isClosed()) {
return false;
}
} catch (Exception e) {
// TODO: handle exception
}
return true;
}
/**
* 3.释放连接 回收
* 判断连接是否可用
* ==>判断空闲线程是否已满
* 没满==》回收连接,放到空闲线程池中
* 已满==》关闭连接
* 活动连接池移除该连接
*/
public synchronized void releaseConnection(Connection connection){
//判断连接是否可用
if(isAvailable(connection)){
//判断空闲线程是否已满
if(freeConnection.size() < dbBean.getMaxConnections()){
// 空闲线程没有满,回收连接
freeConnection.add(connection);
}else {
// 空闲线程已经满
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//活动连接池移除该连接
activeConnection.remove(connection);
//连接数减一
connNum--;
notifyAll();
}
}
}