Day31 接昨天

12        BUg优化

12.1        技术问题

正则表达式

Pattern和Matcher

Pattern是正则表达式引擎

Matcher是匹配器

Matches : 全词匹配

Find : 任意位置

lookingAt : 从前往后匹配

package com;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class TestRegex_01 {

         public static void main(String[] args) {

                  String regex = "\\d{11}";

                  String tel = "131131131121";

                  // 创建引擎

                  Pattern pattern = Pattern.compile(regex);

                  // 创建匹配器

                  Matcher matcher = pattern.matcher(tel);

                  // System.out.println(matcher.matches());

                  // System.out.println(matcher.find());

                  System.out.println(matcher.lookingAt());

                  tel = "我的电话是13113113111";

                  regex = "我的电话是(\\d{11})";

                  pattern = Pattern.compile(regex);

                  matcher = pattern.matcher(tel);

                  matcher.find();

                  System.out.println(matcher.group(1));

         }

}

12.2         封装工具类

package com.tledu.zrz.util;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

 * 正则表达式工具类

 *

 * @author 天亮教育-帅气多汁你泽哥

 * @Date 2021年11月12日 上午9:37:50

 */

public class RegexUtil {

         /**

          * 格式验证

          *

          * @param regex

          * @param input

          * @return

          */

         public static boolean isValid(String regex, String input) {

                  Pattern pattern = Pattern.compile(regex);

                  // 创建匹配器

                  Matcher matcher = pattern.matcher(input);

                  return matcher.matches();

         }

         /**

          * 数据提取

          *

          * @param regex

          * @param input

          * @param groupIndex

          * @return

          */

         public static String getMatchContent(String regex, String input,

                          int groupIndex) {

                  Pattern pattern = Pattern.compile(regex);

                  // 创建匹配器

                  Matcher matcher = pattern.matcher(input);

                  if (matcher.find()) {

                          return matcher.group(groupIndex);

                  }

                  return null;

         }

         public static String getMatchContent(String regex, String input) {

                  return getMatchContent(regex, input, 0);

         }

}

12.3        测试工具类

package com;

import com.tledu.zrz.util.RegexUtil;

public class TestRegex_02 {

         public static void main(String[] args) {

                  String regex = "\\d{11}";

                  String tel = "13113113111";

                  System.out.println(RegexUtil.isValid(regex, tel));

                  tel = "我的电话是13113113111";

                  regex = "我的电话是(\\d{11})";

                  System.out.println(RegexUtil.getMatchContent(regex, tel,1));

         }

}

12.4        业务问题

package com.tledu.zrz.util;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

 * 正则表达式工具类

 *

 */

public class RegexUtil {

         private static String regexIP = "((25[0-5]|2[0-4]\\d|[1]{1}\\d{1}\\d{1}|[1-9]{1}\\d{1}|\\d{1})($|(?!\\.$)\\.)){4}";

         /**

          * 校验IP

          * @param ip

          * @return

          */

         public static boolean isValidIP(String ip) {

                  return isValid(regexIP, ip);

         }

         /**

          * 格式验证

          *

          * @param regex

          * @param input

          * @return

          */

         public static boolean isValid(String regex, String input) {

                  Pattern pattern = Pattern.compile(regex);

                  // 创建匹配器

                  Matcher matcher = pattern.matcher(input);

                  return matcher.matches();

         }

         /**

          * 数据提取

          *

          * @param regex

          * @param input

          * @param groupIndex

          * @return

          */

         public static String getMatchContent(String regex, String input,

                          int groupIndex) {

                  Pattern pattern = Pattern.compile(regex);

                  // 创建匹配器

                  Matcher matcher = pattern.matcher(input);

                  if (matcher.find()) {

                          return matcher.group(groupIndex);

                  }

                  return null;

         }

         public static String getMatchContent(String regex, String input) {

                  return getMatchContent(regex, input, 0);

         }

}

12.5测试

package com;

import com.tledu.zrz.util.RegexUtil;

public class TestRegex_03 {

         public static void main(String[] args) {

                  String ip = "1.1.322.5";

                  System.out.println(RegexUtil.isValidIP(ip));

         }

}

12.6应用

校验应该写在对外提供的接口处

getLocation

Day31 接昨天

13        性能调优

13.1相关技术

13.1.1硬件

内存,CPU.磁盘,网络等 都可以实现性能提高

13.1.2软件

13.1.2.1直接调优

哪里慢,就调哪里,不需要花里胡哨的

主要指算法问题,内核层面,难度较大,大部分都是非直接调优

13.1.2.2迂回调优

通过设计,策略,可以通过不用面对底层优化的难题

1.3.1.2.3迂回调优方向

缓存策略

通过添加时间断点,测试得出,结构化耗时较多

Day31 接昨天

一开始,我们一次运行中,先后校验两个IP,需要结构化两次

后来我们使用静态语句块解决了这个问题

做到一次生命周期中,只会结构化一次

现在面临的问题是,需要让多次生命周期,使用同一个结构化之后的对象,就可以解决当前的问题可以使用序列化和反序列化解决

13.1.3        序列化和反序列化

序列化 : 将内存中对象保存到硬盘中

反序列化 : 把硬盘中对象载入到内存

被序列化的对象必须实现serlizable接口

13.2首次调优

13.2.1技术问题

package com;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class TestSerinalizable_01 {

         public static void main(String[] args) throws Exception{

                 User user =new User(11);

                 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/x"));

                 oos.writeObject(user);

                 oos.close();  

                 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/x"));

                 Object o = ois.readObject();

                 System.out.println(o);

         }

}

class User implements Serializable{

         private int age;

         public User(int age) {

                 super();

                 this.age = age;

         }

         @Override

         public String toString() {

                 return "User [age=" + age + "]";

         }

}

 

13.2.2封装工具类

package com.tledu.zrz.util;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class SerDeUtil {

         /**

          * 写入

          *

          * @param obj

          * @param objFilePath

          * @throws IOException

          */

         public static void saveObject(Object obj, String objFilePath)

                          throws IOException {

                 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

                                   objFilePath));

                 oos.writeObject(obj);

                 oos.close();

         }

         /**

          * 读取

          *

          * @param objFilePath

          * @return

          * @throws ClassNotFoundException

          * @throws IOException

          */

         public static Object getObj(String objFilePath)

                          throws ClassNotFoundException, IOException {

                 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

                                   objFilePath));

                 Object o = ois.readObject();

                 return o;

         }

}

13.2.3测试

package com;

import com.tledu.zrz.util.SerDeUtil;

public class TestSerinalizable_02 {

         public static void main(String[] args) throws Exception{

                 User user =new User(11);

                 SerDeUtil.saveObject(user, "D:/a");

                

                 System.out.println(SerDeUtil.getObj("D:/a"));

         }

}

13.2.4初始化优化

只有第一次才序列化,其余的都反序列化即可

判断该文件是否存在,如果存在,就反序列化获取,如果不存在,就序列化写出

注意

public class IPAndLocationPojo implements Serializable,

                  Comparable<IPAndLocationPojo> {

package com.tledu.zrz.manager;

import com.tledu.zrz.pojo.IPAndLocationPojo;

import com.tledu.zrz.util.FileOperatorUtil;

import com.tledu.zrz.util.IPUtil;

import com.tledu.zrz.util.RegexUtil;

import com.tledu.zrz.util.SerDeUtil;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

/**

 * 该类为项目中管理类

 *

 * @author 天亮教育-帅气多汁你泽哥

 * @Date 2021年11月11日 上午11:45:19

 */

public class DataProcessManager {

         private static IPAndLocationPojo[] ipLocationPojoArr = null;

         static {

                  // 地址库文件

                  String ipLibrartPath = "ip_location_relation.txt";

                  // 字符编码

                  String encoding = "utf-8";

                  // 文件地址

                  String serde_obj_filepath = "ipLibObj.data";

                  // 判断序列化文件是否存在

                  boolean isInit = new File(serde_obj_filepath).exists();

                  // 存在就反序列化获取

                  if (isInit) {

                          try {

                                   Object object = SerDeUtil.getObj(serde_obj_filepath);

                                   ipLocationPojoArr = (IPAndLocationPojo[]) object;

                          } catch (ClassNotFoundException | IOException e) {

                                   e.printStackTrace();

                          }

                  }else{

                  // 不存在就序列化写出

                          // 获取数据

                          List<IPAndLocationPojo> ipAndLocationPojos = null;

                          try {

                                   ipAndLocationPojos = DataProcessManager.getPojoList(ipLibrartPath,

                                                    encoding);

                          } catch (IOException e) {

                                   e.printStackTrace();

                          }

                          // 转换为数组

                          ipLocationPojoArr = DataProcessManager

                                            .convertListToArrayAndSort(ipAndLocationPojos);

                          try {

                                   SerDeUtil.saveObject(ipLocationPojoArr, serde_obj_filepath);

                          } catch (IOException e) {

                                   e.printStackTrace();

                          }

                  }

        

         }

         /**

          * 对外提供的接口,入参IP出参地址

          *

          * @param ip

          * @return

          */

         public static String getLocation(String ip) {

                  if (RegexUtil.isValidIP(ip)) {

                          int index = DataProcessManager.binaraySearch(ipLocationPojoArr, ip);

                          return index == -1 ? "未找到" : ipLocationPojoArr[index].getLocation();

                  }else{

                          return "IP地址格式不正确,请重新输入";

                  }

         }

         /**

          * 业务类对应的二分法

          *

          * @param ipLocationPojoArr

          *            数组

          * @param ip

          *            ip

          * @return 索引

          */

         public static int binaraySearch(IPAndLocationPojo[] ipLocationPojoArr,

                          String ip) {

                  // 转换为long类型

                  long ipLong = IPUtil.ipToLong(ip);

                  int startIndex = 0;

                  int endIndex = ipLocationPojoArr.length - 1;

                  int m = (endIndex + startIndex) / 2;

                  while (startIndex <= endIndex) {

                          // 大于等于起始 小于等于结束 说明找到了

                          // 小于起始 在前半截

                          // 大于结束 在后半截

                          if (ipLong > ipLocationPojoArr[m].getEndIPLong()) {

                                   startIndex = m + 1;

                          } else if (ipLong < ipLocationPojoArr[m].getStartIPLong()) {

                                   endIndex = m - 1;

                          } else {

                                   return m;

                          }

                          m = (startIndex + endIndex) / 2;

                  }

                  return -1;

         }

         /**

          * 将对象集合转换为对象数组并排序

          *

          * @param pojoList

          * @return

          */

         public static IPAndLocationPojo[] convertListToArrayAndSort(

                          List<IPAndLocationPojo> pojoList) {

                  // 转换为数组

                  IPAndLocationPojo[] ipLocationPojoArr = new IPAndLocationPojo[pojoList

                                   .size()];

                  pojoList.toArray(ipLocationPojoArr);

                  // 排序

                  Arrays.sort(ipLocationPojoArr);

                  return ipLocationPojoArr;

         }

         /**

          * 把读取到的List<String> 转换为 List<IPAndLocationPojo>

          *

          * @param ipLibrartPath

          * @param encoding

          * @return

          * @throws IOException

          */

         public static List<IPAndLocationPojo> getPojoList(String ipLibrartPath,

                          String encoding) throws IOException {

                  List<String> lineList = FileOperatorUtil.getLineList(ipLibrartPath,

                                   encoding);

                  List<IPAndLocationPojo> ipAndLocationPojos = new ArrayList<IPAndLocationPojo>();

                  // 遍历 获取每一行

                  for (String string : lineList) {

                          if (string == null || string.trim().equals("")) {

                                   continue;

                          }

                          // 以\t分割,得到三个列

                          String[] columnArray = string.split("\t");

                          // 创建结构化对象

                          IPAndLocationPojo ipAndLocationPojo = new IPAndLocationPojo(

                                            columnArray[0], columnArray[1], columnArray[2]);

                          // 保存到集合中

                          ipAndLocationPojos.add(ipAndLocationPojo);

                  }

                  return ipAndLocationPojos;

         }

}

13.3IO调优

加入序列化和反序列化之后,导致效率更低,并且第二个运行要比第一次还慢,说明反序列化有问题

缓冲流 : 缓冲流是IO流的缓冲区,用来提高IO的效率

首次 7000

非首次 20000

文件大小为 38.3M

13.3.1引入缓冲流

package com.tledu.zrz.util;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class SerDeUtil {

         /**

          * 对象写出,引入缓冲流

          *

          * @param obj

          * @param objFilePath

          * @param cacheByyeArrayLength

          * @throws IOException

          */

         public static void saveObject(Object obj, String objFilePath,

                          int cacheByyeArrayLength) throws IOException {

                 FileOutputStream fos = new FileOutputStream(objFilePath);

                 // 字节数组缓冲流

                 ByteArrayOutputStream baos = new ByteArrayOutputStream(

                                   cacheByyeArrayLength);

                 ObjectOutputStream oos = new ObjectOutputStream(baos);

                 oos.writeObject(obj);

                 byte[] bytes = baos.toByteArray();

                 fos.write(bytes);

                 oos.close();

                 fos.close();

         }

         /**

          * 获取,引入缓冲流

          *

          * @param objFilePath

          * @param cacheByyeArrayLength

          * @return

          * @throws ClassNotFoundException

          * @throws IOException

          */

         public static Object getObj(String objFilePath, int cacheByyeArrayLength)

                          throws ClassNotFoundException, IOException {

                 FileInputStream fis = new FileInputStream(objFilePath);

                 byte[] bytes = new byte[cacheByyeArrayLength];

                 fis.read(bytes);

                 fis.close();

                 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

                 ObjectInputStream ois = new ObjectInputStream(bais);

                 Object o = ois.readObject();

                 ois.close();

                 return o;

         }

         /**

          * 写入

          *

          * @param obj

          * @param objFilePath

          * @throws IOException

          */

         public static void saveObject(Object obj, String objFilePath)

                          throws IOException {

                 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

                                   objFilePath));

                 oos.writeObject(obj);

                 oos.close();

         }

         /**

          * 读取

          *

          * @param objFilePath

          * @return

          * @throws ClassNotFoundException

          * @throws IOException

          */

         public static Object getObj(String objFilePath)

                          throws ClassNotFoundException, IOException {

                 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

                                   objFilePath));

                 Object o = ois.readObject();

                 ois.close();

                 return o;

         }

}

13.3.2        调用处更改

Day31 接昨天

Day31 接昨天 

13.4代码标准化

Day31 接昨天 

代码中,出现了好多这些变量,当我们需要更改某一个的时候,不好找

集中管理

13.4.1StaticValue

package com.tledu.zrz.util;

public class StaticValue {

         // 地址库文件

         public static String ipLibrartPath = "ip_location_relation.txt";

         // 字符编码

         public static  String encoding = "utf-8";

         // 文件地址

         public static  String serde_obj_filepath = "ipLibObj.data";

         // 根据文件大小,计算长度

         public static  int cacheByteArrayLength = 40*1024*1024;

}

13.4.2应用

                 // 判断序列化文件是否存在

                  File file = new File(StaticValue.serde_obj_filepath);

                  boolean isInit = file.exists();

                  // 存在就反序列化获取

                  if (isInit) {

                          try {

                                   Object object = SerDeUtil.getObj(

                                                    StaticValue.serde_obj_filepath,

                                                    StaticValue.cacheByteArrayLength);

                                   ipLocationPojoArr = (IPAndLocationPojo[]) object;

                          } catch (ClassNotFoundException | IOException e) {

                                   e.printStackTrace();

                          }

                  } else {

                          // 不存在就序列化写出

                          // 获取数据

                          List<IPAndLocationPojo> ipAndLocationPojos = null;

                          try {

                                   ipAndLocationPojos = DataProcessManager.getPojoList(

                                                    StaticValue.ipLibrartPath, StaticValue.encoding);

                          } catch (IOException e) {

                                   e.printStackTrace();

                          }

                          // 转换为数组

                          ipLocationPojoArr = DataProcessManager

                                            .convertListToArrayAndSort(ipAndLocationPojos);

                          try {

                                   SerDeUtil.saveObject(ipLocationPojoArr,

                                                    StaticValue.serde_obj_filepath,

                                                    StaticValue.cacheByteArrayLength);

                          } catch (IOException e) {

                                   e.printStackTrace();

                          }

                  }

14优化进阶

14.1.1        IO优化

直接优化 : 提高IO效率

间接优化 : 数据大小也会应该效率问题

Day31 接昨天

文件大小变动Day31 接昨天

首次2500 非首次 520-600

 

 

 

上一篇:正则表达式


下一篇:MIT 6.828 JOS学习笔记17. Lab 3.1 Part A User Environments