From 00f612ee127381f0029473977323bd833a8ac4ed Mon Sep 17 00:00:00 2001 From: Guide Date: Thu, 4 Apr 2024 16:11:39 +0800 Subject: [PATCH] =?UTF-8?q?[docs=20update]=E9=83=A8=E5=88=86=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/collection/java-collection-questions-01.md | 2 +- docs/java/concurrent/java-concurrent-questions-03.md | 10 +++++----- docs/java/concurrent/java-thread-pool-summary.md | 10 +++++----- docs/open-source-project/practical-project.md | 2 +- docs/system-design/security/encryption-algorithms.md | 10 ++++++---- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/java/collection/java-collection-questions-01.md b/docs/java/collection/java-collection-questions-01.md index aedc4d35..ed203092 100644 --- a/docs/java/collection/java-collection-questions-01.md +++ b/docs/java/collection/java-collection-questions-01.md @@ -18,7 +18,7 @@ head: ### Java 集合概览 -Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 `Collection`接口,主要用于存放单一元素;另一个是 `Map` 接口,主要用于存放键值对。对于`Collection` 接口,下面又有三个主要的子接口:`List`、`Set` 、 `Queue`、`Map`。 +Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 `Collection`接口,主要用于存放单一元素;另一个是 `Map` 接口,主要用于存放键值对。对于`Collection` 接口,下面又有三个主要的子接口:`List`、`Set` 、 `Queue`。 Java 集合框架如下图所示: diff --git a/docs/java/concurrent/java-concurrent-questions-03.md b/docs/java/concurrent/java-concurrent-questions-03.md index 03055ed1..0fba1a82 100644 --- a/docs/java/concurrent/java-concurrent-questions-03.md +++ b/docs/java/concurrent/java-concurrent-questions-03.md @@ -311,22 +311,22 @@ public ScheduledThreadPoolExecutor(int corePoolSize) { - `keepAliveTime`:线程池中的线程数量大于 `corePoolSize` 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 `keepAliveTime`才会被回收销毁。 - `unit` : `keepAliveTime` 参数的时间单位。 - `threadFactory` :executor 创建新线程的时候会用到。 -- `handler` :饱和策略(后面会单独详细介绍一下)。 +- `handler` :拒绝策略(后面会单独详细介绍一下)。 下面这张图可以加深你对线程池中各个参数的相互关系的理解(图片来源:《Java 性能调优实战》): ![线程池各个参数的关系](https://oss.javaguide.cn/github/javaguide/java/concurrent/relationship-between-thread-pool-parameters.png) -### 线程池的饱和策略有哪些? +### 线程池的拒绝策略有哪些? 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任务时,`ThreadPoolExecutor` 定义一些策略: - `ThreadPoolExecutor.AbortPolicy`:抛出 `RejectedExecutionException`来拒绝新任务的处理。 -- `ThreadPoolExecutor.CallerRunsPolicy`:调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 +- `ThreadPoolExecutor.CallerRunsPolicy`:调用执行自己的线程运行任务,也就是直接在调用`execute`方法的线程中运行(`run`)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果你的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。 - `ThreadPoolExecutor.DiscardPolicy`:不处理新任务,直接丢弃掉。 - `ThreadPoolExecutor.DiscardOldestPolicy`:此策略将丢弃最早的未处理的任务请求。 -举个例子:Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 饱和策略来配置线程池的时候,默认使用的是 `AbortPolicy`。在这种饱和策略下,如果队列满了,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 异常来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。如果不想丢弃任务的话,可以使用`CallerRunsPolicy`。`CallerRunsPolicy` 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务 +举个例子:Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 拒绝策略来配置线程池的时候,默认使用的是 `AbortPolicy`。在这种拒绝策略下,如果队列满了,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 异常来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。如果不想丢弃任务的话,可以使用`CallerRunsPolicy`。`CallerRunsPolicy` 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务。 ```java public static class CallerRunsPolicy implements RejectedExecutionHandler { @@ -359,7 +359,7 @@ public static class CallerRunsPolicy implements RejectedExecutionHandler { 1. 如果当前运行的线程数小于核心线程数,那么就会新建一个线程来执行任务。 2. 如果当前运行的线程数等于或大于核心线程数,但是小于最大线程数,那么就把该任务放入到任务队列里等待执行。 3. 如果向任务队列投放任务失败(任务队列已经满了),但是当前运行的线程数是小于最大线程数的,就新建一个线程来执行任务。 -4. 如果当前运行的线程数已经等同于最大线程数了,新建线程将会使当前运行的线程超出最大线程数,那么当前任务会被拒绝,饱和策略会调用`RejectedExecutionHandler.rejectedExecution()`方法。 +4. 如果当前运行的线程数已经等同于最大线程数了,新建线程将会使当前运行的线程超出最大线程数,那么当前任务会被拒绝,拒绝策略会调用`RejectedExecutionHandler.rejectedExecution()`方法。 ### 如何给线程池命名? diff --git a/docs/java/concurrent/java-thread-pool-summary.md b/docs/java/concurrent/java-thread-pool-summary.md index 9dff3a50..8192890c 100644 --- a/docs/java/concurrent/java-thread-pool-summary.md +++ b/docs/java/concurrent/java-thread-pool-summary.md @@ -125,13 +125,13 @@ public class ScheduledThreadPoolExecutor - `keepAliveTime`:线程池中的线程数量大于 `corePoolSize` 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 `keepAliveTime`才会被回收销毁。 - `unit` : `keepAliveTime` 参数的时间单位。 - `threadFactory` :executor 创建新线程的时候会用到。 -- `handler` :饱和策略(后面会单独详细介绍一下)。 +- `handler` :拒绝策略(后面会单独详细介绍一下)。 下面这张图可以加深你对线程池中各个参数的相互关系的理解(图片来源:《Java 性能调优实战》): ![线程池各个参数的关系](https://oss.javaguide.cn/github/javaguide/java/concurrent/relationship-between-thread-pool-parameters.png) -**`ThreadPoolExecutor` 饱和策略定义:** +**`ThreadPoolExecutor` 拒绝策略定义:** 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任务时,`ThreadPoolExecutor` 定义一些策略: @@ -142,7 +142,7 @@ public class ScheduledThreadPoolExecutor 举个例子: -举个例子:Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 饱和策略来配置线程池的时候,默认使用的是 `AbortPolicy`。在这种饱和策略下,如果队列满了,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 异常来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。如果不想丢弃任务的话,可以使用`CallerRunsPolicy`。`CallerRunsPolicy` 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务 +举个例子:Spring 通过 `ThreadPoolTaskExecutor` 或者我们直接通过 `ThreadPoolExecutor` 的构造函数创建线程池的时候,当我们不指定 `RejectedExecutionHandler` 拒绝策略来配置线程池的时候,默认使用的是 `AbortPolicy`。在这种拒绝策略下,如果队列满了,`ThreadPoolExecutor` 将抛出 `RejectedExecutionException` 异常来拒绝新来的任务 ,这代表你将丢失对这个任务的处理。如果不想丢弃任务的话,可以使用`CallerRunsPolicy`。`CallerRunsPolicy` 和其他的几个策略不同,它既不会抛弃任务,也不会抛出异常,而是将任务回退给调用者,使用调用者的线程来执行任务 ```java public static class CallerRunsPolicy implements RejectedExecutionHandler { @@ -325,7 +325,7 @@ public class ThreadPoolExecutorDemo { - `keepAliveTime` : 等待时间为 1L。 - `unit`: 等待时间的单位为 TimeUnit.SECONDS。 - `workQueue`:任务队列为 `ArrayBlockingQueue`,并且容量为 100; -- `handler`:饱和策略为 `CallerRunsPolicy`。 +- `handler`:拒绝策略为 `CallerRunsPolicy`。 **输出结构**: @@ -413,7 +413,7 @@ Finished all threads // 任务全部执行完了才会跳出来,因为executo 1. 如果当前运行的线程数小于核心线程数,那么就会新建一个线程来执行任务。 2. 如果当前运行的线程数等于或大于核心线程数,但是小于最大线程数,那么就把该任务放入到任务队列里等待执行。 3. 如果向任务队列投放任务失败(任务队列已经满了),但是当前运行的线程数是小于最大线程数的,就新建一个线程来执行任务。 -4. 如果当前运行的线程数已经等同于最大线程数了,新建线程将会使当前运行的线程超出最大线程数,那么当前任务会被拒绝,饱和策略会调用`RejectedExecutionHandler.rejectedExecution()`方法。 +4. 如果当前运行的线程数已经等同于最大线程数了,新建线程将会使当前运行的线程超出最大线程数,那么当前任务会被拒绝,拒绝策略会调用`RejectedExecutionHandler.rejectedExecution()`方法。 ![图解线程池实现原理](https://oss.javaguide.cn/github/javaguide/java/concurrent/thread-pool-principle.png) diff --git a/docs/open-source-project/practical-project.md b/docs/open-source-project/practical-project.md index c96fd053..4d63af8f 100644 --- a/docs/open-source-project/practical-project.md +++ b/docs/open-source-project/practical-project.md @@ -27,7 +27,6 @@ icon: project - [paicoding](https://github.com/itwanger/paicoding):一款好用又强大的开源社区,基于 Spring Boot 系列主流技术栈,附详细的教程。 - [forest](https://github.com/rymcu/forest):下一代的知识社区系统,可以自定义专题和作品集。后端基于 SpringBoot + Shrio + MyBatis + JWT + Redis,前端基于 Vue + NuxtJS + Element-UI。 -- [vhr](https://github.com/lenve/vhr "vhr"):微人事是一个前后端分离的人力资源管理系统,项目采用 SpringBoot+Vue 开发。 - [community](https://github.com/codedrinker/community):开源论坛、问答系统,现有功能提问、回复、通知、最新、最热、消除零回复功能。功能持续更新中…… 技术栈 Spring、Spring Boot、MyBatis、MySQL/H2、Bootstrap。 - [VBlog](https://github.com/lenve/VBlog):V 部落,Vue+SpringBoot 实现的多用户博客管理平台! - [My-Blog](https://github.com/ZHENFENG13/My-Blog): SpringBoot + Mybatis + Thymeleaf 等技术实现的 Java 博客系统,页面美观、功能齐全、部署简单及完善的代码,一定会给使用者无与伦比的体验。 @@ -49,6 +48,7 @@ icon: project - [HOJ](https://gitee.com/himitzh0730/hoj):分布式架构的在线测评平台 OJ ,功能非常全面,支持刷题、训练、比赛、评测等功能。 - [VOJ](https://github.com/simplefanC/voj):基于微服务架构的高性能在线评测系统。拥有本地判题服务,同时支持其它知名 OJ (HDU、POJ...) 的远程判题。采用现阶段流行技术实现,采用 Docker 容器化部署。 - [OnlineJudge](https://github.com/SDUOJ/OnlineJudge):基于微服务架构的在线评测系统,支持多种国际赛制支持(ICPC/OI/IOI),采用 Docker 容器化部署。 +- [sg-exam](https://gitee.com/wells2333/sg-exam):方便易用、高颜值的教学管理平台,提供多租户、权限管理、考试、练习、在线学习等功能。 - [uexam](https://gitee.com/mindskip/uexam):功能全面的在线考试系统,开发部署简单快捷、界面设计友好、代码结构清晰。相关阅读:[好一个 Spring Boot 开源在线考试系统!解决了我的燃眉之急](http://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzg2OTA0Njk0OA%3D%3D%26mid%3D2247491585%26idx%3D1%26sn%3D8d3c6768c22e72d6bfcbeee9624886a7%26chksm%3Dcea1afcaf9d626dc918760289c37025ad526f6255786bc198d2402203df64c873ad7934f58df%26scene%3D178%26cur_album_id%3D1345382825083895808%23rd) 。 - [PassJava-Platform](https://github.com/Jackson0714/PassJava-Platform):基于微服务架构的面试刷题小程序!相关阅读:[一个基于 Spring Cloud 的面试刷题系统。面试、毕设、项目经验一网打尽](http://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzg2OTA0Njk0OA%3D%3D%26mid%3D2247497045%26idx%3D1%26sn%3D577175bfd6c040a0df5a494fce6f9758%26chksm%3Dcea1ba9ef9d633883a2e213c0fb9a88bdc87051347d4b3fad2c2befb65d8b16e1ea81d8146dd%26scene%3D178%26cur_album_id%3D1345382825083895808%23rd)。 diff --git a/docs/system-design/security/encryption-algorithms.md b/docs/system-design/security/encryption-algorithms.md index 94573d69..d4db8222 100644 --- a/docs/system-design/security/encryption-algorithms.md +++ b/docs/system-design/security/encryption-algorithms.md @@ -32,17 +32,19 @@ tag: - 不能从哈希值还原出原始数据。 - 原始数据的任何改变都会导致哈希值的巨大变化。 -哈希算法分为两类: +哈希算法可以简单分为两类: -- **加密哈希算法**:安全性较高的哈希算法,它可以提供一定的数据完整性保护和数据防篡改能力,能够抵御一定的攻击手段,安全性相对较高,适用于对安全性要求较高的场景。例如,SHA-256、SHA-512、SM3、Bcrypt 等等。 -- **非加密哈希算法**:安全性相对较低的哈希算法,易受到暴力破解、冲突攻击等攻击手段的影响,但性能较高,适用于对安全性没有要求的业务场景。例如,CRC32、MurMurHash3 等等。 +1. **加密哈希算法**:安全性较高的哈希算法,它可以提供一定的数据完整性保护和数据防篡改能力,能够抵御一定的攻击手段,安全性相对较高,但性能较差,适用于对安全性要求较高的场景。例如 SHA2、SHA3、SM3、RIPEMD-160、BLAKE2、SipHash 等等。 +2. **非加密哈希算法**:安全性相对较低的哈希算法,易受到暴力破解、冲突攻击等攻击手段的影响,但性能较高,适用于对安全性没有要求的业务场景。例如 CRC32、MurMurHash3、SipHash 等等。 + +除了这两种之外,还有一些特殊的哈希算法,例如安全性更高的**慢哈希算法**。 常见的哈希算法有: - MD(Message Digest,消息摘要算法):MD2、MD4、MD5 等,已经不被推荐使用。 - SHA(Secure Hash Algorithm,安全哈希算法):SHA-1 系列安全性低,SHA2,SHA3 系列安全性较高。 - 国密算法:例如 SM2、SM3、SM4,其中 SM2 为非对称加密算法,SM4 为对称加密算法,SM3 为哈希算法(安全性及效率和 SHA-256 相当,但更适合国内的应用环境)。 -- Bcrypt(密码哈希算法):基于 Blowfish 加密算法的密码哈希算法,专门为密码加密而设计,安全性高。 +- Bcrypt(密码哈希算法):基于 Blowfish 加密算法的密码哈希算法,专门为密码加密而设计,安全性高,属于慢哈希算法。 - MAC(Message Authentication Code,消息认证码算法):HMAC 是一种基于哈希的 MAC,可以与任何安全的哈希算法结合使用,例如 SHA-256。 - CRC:(Cyclic Redundancy Check,循环冗余校验):CRC32 是一种 CRC 算法,它的特点是生成 32 位的校验值,通常用于数据完整性校验、文件校验等场景。 - SipHash:加密哈希算法,它的设计目的是在速度和安全性之间达到一个平衡,用于防御[哈希泛洪 DoS 攻击](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf)。Rust 默认使用 SipHash 作为哈希算法,从 Redis4.0 开始,哈希算法被替换为 SipHash。