1.什么是设计模式:前人解决问题的套路 ,经验。可以复用的代码设计经验,良好的编写代码的风格
基础概念
1,创建型模式看完了
1.模板设计模式(abstract)
2.设计模式 反射+策略模式来替换 if-else
似乎可以完全取代if else和switch
1.策略模式简介
策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口
和 具体行为的实现
。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化
下边链接的支付可以替换成不同的任务,物流啦,里边逻辑特别清晰
现在这里就举一个例子。
首先策略模式需要先有了解,我们常用策略模式解决实际开发中的if else特别多的场景。但是在实际的开发中,真正单独只用策略模式的场景还是很少的。我们需要利用Spring的注入功能,实现根据不同的入参,跳转到不同的实现类中,以此来减少if else的使用。
举个场景:假如我们做物流系统,需要根据前段传过来的渠道参数,来定制化不同的规则校验逻辑。这里我们距离alibaba渠道和wechat渠道。那么我们应该怎么做呢?
大致思路:
1、定义抽象接口,提取一个抽象方法,这个方法的具体实现在各个渠道的类中
2、在service层,通过实现ApplicationContextAware接口,获取spring的applicationContext
3、在service层,通过入参确定需要跳转到哪个类实现定制的渠道规则。
java设计模式实战-(反射+策略模式)_奔跑的扫地僧的博客-CSDN博客_反射+策略模式
反射+策略模式来替换 if-else(一)_就喜欢吃丶的博客-CSDN博客
=======
二.算法-冒泡排序(不规则的数组,按照顺序排列好)
三.二分查找(当一个数组是按照从小到大排列的那么可以用这个算法)
四. 递归算法
应用场景:树形菜单
问题:如何从数据库的表中获取数据,
Java 递归实现树形菜单_Alexure的博客-CSDN博客_java递归生成树形菜单
五。MD5(唯一性)
应用场景有哪些:
3.1 一致性校验
用于文件传输,来确保接收的文件和传输的文件的一致性,防止在传输过程中被篡改。
3.2 数字签名
支付领域应用MD5,保证支付信息不会被篡改。
3.3 安全访问认证
设计用户登录时,用户密码如果明文存入数据库,就存在被泄露的风险。因为MD5加密是不可逆的,对用户密码进行MD5加密存入数据,就可保证密码不会被泄露。
思路:入参是文件的路径,最后返回md5的128位的字节。
MD5信息摘要算法,,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
每个文件对应的md5值是固定的,文件内容发生变化时,md5值也会发生变化。文件内容相同时,md5值相同。所以,md5值可以作为文件的唯一标识符。
如果想知道下载的文件和原文件是否一模一样,就可以查看文件的md5值。
如果下载的文件的md5值和公布出来的md5值相同,那么下载的文件是正确的;
如果md5值不相同,说明下载的文件不是正确的,下载的文件不完整,可能在网络下载的过程中出现错误或文件被别人修改。
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
核心都是通过JAVA自带的MessageDigest类来实现。(自己实现, 少)
获取文件MD5值主要分为三个步骤,第一步获取文件的byte信息,第二步通过MessageDigest类进行MD5加密,第三步转换成16进制的MD5码值。
JAVA自带的commons-codec包就提供了获取16进制MD5值的方法。其底层实现上,也是分多次将一个文件读入,类似方法三。所以性能上也不错。(工具类方便,多)
DigestUtils.md5Hex(new FileInputStream(path));
java获取一个文件的md5码_北海冥鱼未眠的博客-CSDN博客_java 获取文件md5
MD5 文件校验_谁是我的程序媛?的博客-CSDN博客_验证文件的md5
提升改进:加盐加次数,提升安全性
java判断文件是否超出指定大小
java判断文件是否超出指定大小_litGrey的博客-CSDN博客_multipartfile 判断文件大小
22222
1.9.4 其他数字摘要算法
package com.atguigu.digest;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.sound.midi.Soundbank;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class DigestDemo1 {
public static void main(String[] args) throws Exception{
// 4124bc0a9335c27f086f24ba207a4912 md5 在线校验
// QSS8CpM1wn8IbyS6IHpJEg== 消息摘要使用的是16进制
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 获取数字摘要对象
String md5 = getDigest(input, "MD5");
System.out.println(md5);
String sha1 = getDigest(input, "SHA-1");
System.out.println(sha1);
String sha256 = getDigest(input, "SHA-256");
System.out.println(sha256);
String sha512 = getDigest(input, "SHA-512");
System.out.println(sha512);
}
private static String toHex(byte[] digest) throws Exception {
// System.out.println(new String(digest));
// base64编码
// System.out.println(Base64.encode(digest));
// 创建对象用来拼接
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 转成 16进制
String s = Integer.toHexString(b & 0xff);
if (s.length() == 1){
// 如果生成的字符只有一个,前面补0
s = "0"+s;
}
sb.append(s);
}
System.out.println("16进制数据的长度:" + sb.toString().getBytes().length);
return sb.toString();
}
private static String getDigest(String input, String algorithm) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 消息数字摘要
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字节长度:" + digest.length);
return toHex(digest);
}
}
1.9.5 获取文件消息摘要
package com.atguigu.digest;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.misc.BASE64Decoder;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.MessageDigest;
public class DigestDemo {
public static void main(String[] args) throws Exception{
String input = "aa";
String algorithm = "MD5";
// sha1 可以实现秒传功能
String sha1 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-1");
System.out.println(sha1);
String sha512 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-512");
System.out.println(sha512);
String md5 = getDigest("aa", "MD5");
System.out.println(md5);
String md51 = getDigest("aa ", "MD5");
System.out.println(md51);
}
private static String getDigestFile(String filePath, String algorithm) throws Exception{
FileInputStream fis = new FileInputStream(filePath);
int len;
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ( (len = fis.read(buffer))!=-1){
baos.write(buffer,0,len);
}
// 获取消息摘要对象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 获取消息摘要
byte[] digest = messageDigest.digest(baos.toByteArray());
System.out.println("密文的字节长度:"+digest.length);
return toHex(digest);
}
private static String getDigest(String input, String algorithm) throws Exception{
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字节长度:"+digest.length);
return toHex(digest);
}
private static String toHex(byte[] digest) {
// System.out.println(new String(digest));
// 消息摘要进行表示的时候,是用16进制进行表示
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 转成16进制
String s = Integer.toHexString(b & 0xff);
// 保持数据的完整性,前面不够的用0补齐
if (s.length()==1){
s="0"+s;
}
sb.append(s);
}
System.out.println("16进制数据的长度:"+ sb.toString().getBytes().length);
return sb.toString();
}
}