编辑
2023-07-06
学习记录
00

汇总

23种设计模式被分为三大类:创建型模式、结构型模式、行为型模式

创建型结构型行为型
单例模式适配器模式观察者模式
工厂方法模式装饰器模式模板方法模式
抽象工厂模式代理模式策略模式
建造者模式外观模式命令模式
原型模式桥接模式职责链模式
-组合模式状态模式
-享元模式访问者模式

七大原则:

  1. 开放封闭原则
  2. 单一职责原则
  3. 依赖倒置原则
  4. 接口隔离原则
  5. 里氏替换原则
  6. 迪米特原则
  7. 合成复用原则

创建型

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。分为饿汉式和懒汉式,饿汉式是直接初始化类对象,而懒汉式是需要使用到对象再初始化

以下是单例模式的示例代码:

java
public class Singleton { private static Singleton instance; private Singleton() { // 私有构造函数,防止其他类从外部创建实例 } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

在这个示例中,Singleton 类是一个单例类,它只有一个实例。通过 getInstance() 方法获取单例实例。如果实例不存在,则创建一个新的实例。

单例模式在软件开发中有很多用途。以下是一些常见的应用场景:

数据库连接池:在一个系统中,数据库连接池的实例只需要一个,通过单例模式可以确保每个线程都使用相同的数据库连接池。

日志记录器:日志记录器通常只需要一个实例,通过单例模式可以确保所有的日志信息都写入同一个日志文件中。

配置管理器:在一个系统中,配置管理器只需要一个实例,通过单例模式可以确保所有的配置信息都来自于同一个实例。

线程池:在一个系统中,线程池只需要一个实例,通过单例模式可以确保所有的任务都分配到同一个线程池中执行。

需要注意的是,单例模式并不是适用于所有的场景。在多线程环境下,需要考虑到线程安全问题,可以使用线程安全的单例实现方式。同时,在某些情况下,可能需要根据不同的需求创建多个实例,因此需要根据具体的需求来决定是否使用单例模式。

编辑
2023-07-05
学习记录
00

汇总

序号锁名称应用
1乐观锁CAS
2悲观锁synchronized、vector、hashtable
3自旋锁 CAS
4可重入锁synchronized、Reentrantlock、Lock
5读写锁ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet
6公平锁Reentrantlock(true)
7非公平锁synchronized、reentrantlock(false)
8共享锁ReentrantReadWriteLock中读锁
9独占锁synchronized、vector、hashtable、ReentrantReadWriteLock中写锁
10重量级锁synchronized
11轻量级锁锁优化技术
12偏向锁锁优化技术
13分段锁concurrentHashMap
14互斥锁 synchronized
15同步锁synchronized
16死锁相互请求对方的资源
17锁粗化锁优化技术
18锁消除锁优化技术

1、乐观锁

乐观锁

乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低,读数据时认为别的线程不会正在进行修改(所以没有上锁)。写数据时,判断当前 与期望值是否相同,如果相同则进行更新(更新期间加锁,保证是原子性的)。

Java中的乐观锁: CAS,比较并替换,比较当前值(主内存中的值),与预期值(当前线程中的值,主内存中值的一份拷贝)是否一样,一样则更新,否则继续进行CAS操作。

如上图所示,可以同时进行读操作,读的时候其他线程不能进行写操作。

2、悲观锁

悲观锁

悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次去拿数据的时候都认为其他线程会修改,所以每次读写数据都会认为其他线程会修改,所以每次读写数据时都会上锁。其他线程想要读写这个数据时,会被这个线程block,直到这个线程释放锁然后其他线程获取到锁。

Java中的悲观锁: synchronized修饰的方法和方法块、ReentrantLock。

如上图所示,只能有一个线程进行读操作或者写操作,其他线程的读写操作均不能进行。

编辑
2023-07-01
前端
00

安装yarn

查询当前镜像

npm get registry

全局安装yarn

npm install -g yarn

看一下yarn版本,运行以下命令

yarn -v

改为淘宝镜像

yarn config set registry https://registry.npm.taobao.org 最新地址

npm config set registry https://registry.npmmirror.com

安装项目依赖

yarn install

运行项目

yarn run dev

打包

yarn run build
编辑
2023-06-29
学习记录
00

简述

Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。

Deque有三种用途:

普通队列(一端进另一端出):

Queue queue = new LinkedList()或Deque deque = new LinkedList()

双端队列(两端都可进出)

Deque deque = new LinkedList()

堆栈

Deque deque = new LinkedList()

注意:Java堆栈Stack类已经过时,Java官方推荐使用Deque替代Stack使用。Deque堆栈操作方法:push()、pop()、peek()。

Deque是一个线性collection,支持在两端插入和移除元素。名称 deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。大多数 Deque 实现对于它们能够包含的元素数没有固定限制,但此接口既支持有容量限制的双端队列,也支持没有固定大小限制的双端队列。

此接口定义在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是专为使用有容量限制的 Deque 实现设计的;在大多数实现中,插入操作不能失败。

下表总结了上述 12 种方法:

第一个元素 (头部)最后一个元素 (尾部)
抛出异常特殊值抛出异常特殊值
插入addFirst(e)offerFirst(e)addLast(e)
删除removeFirst()pollFirst()removeLast()
检查getFirst()peekFirst()getLast()

Deque接口扩展(继承)了 Queue 接口。在将双端队列用作队列时,将得到 FIFO(先进先出)行为。将元素添加到双端队列的末尾,从双端队列的开头移除元素。从 Queue 接口继承的方法完全等效于 Deque 方法,如下表所示:

Queue方法等效Deque方法
add(e)addLast(e)
offer(e)offerLast(e)
remove()removeFirst()
poll()pollFirst()
element()getFirst()
peek()peekFirst()

双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:

堆栈方法等效Deque方法
push(e)addFirst(e)
pop()removeFirst()
peek()peekFirst()

方法汇总

方法说明
add方法往队列尾部加入元素
addFirst方法往队列首部加入元素
addLast方法往队列尾部加入元素
contains方法判断队列中是否包含某个元素
descendingIterator方法以相反的顺序返回deque
element方法检索但不删除返回队列的头部
getFirst方法与element相同,检索但不删除返回第一个元素,具体不知道为什么会有重复的方法,应该是版本更新兼容吧,就语义来说这个好一点
getLast方法检索并返回最后一个元素
iterator方法以正确的顺序返回此元素的迭代器
offer方法将指定元素插入该元素的尾部,返回true或者false,与add的区别是add当没有可用空间时会抛异常,而offer返回false
offerFirst方法在双端队列头部插入元素
offerLast方法在双端队列尾部插入元素,同offer一样,为了Queue和Deque兼容
peek()方法和peekFirst/peekLast方法返回但不删除双端队列的首元素/尾元素
poll方法和pollFirst/pollLast方法poll检索并删除队列的首元素,pollFirst也是,pollLast检索并删除队列的尾元素
pop方法pop从这个deque表示的堆栈中弹出一个元素,与poll不同的是pop当为空时会报异常,而poll会返回null
push方法在此deque的首部添加元素
remove方法以及removeFirst/removeLast方法remove和removeFirst检索并删除队列中第一个元素,removeLast检索并删除队列中最后一个元素(同poll相同,就不演示了)
size方法返回此的确中的元素数
编辑
2023-06-28
学习记录
00

RequestParam

@RequestParam:接收来自RequestHeader中,即请求头。通常用于GET请求,例如:

java
@GetMapping("/hello") public String hello(@RequestParam(name = "id") Long id){ System.out.println("hello " + id); return "hello message"; }

POST请求 由于@RequestParam是用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容的,所以在postman中,要选择body的类型为 x-www-form-urlencoded,这样在headers中就自动变为了 Content-Type : application/x-www-form-urlencoded 编码格式。如下所示:

java
@PostMapping("/save") public String hello(@RequestParam(name = "id") Long id, @RequestParam("name") String name, @RequestParam("password") String password){ System.out.println(user); return "hello message"; }

RequstBody

注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。

就application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

java
@PostMapping("/saveBatch") public String saveBatch(@RequestBody @Validated List<User> list){ list.forEach(System.out::println); return "saveBatch success"; }