JavaSE-项目小结-IP归属地查询(本地IP地址库)
一、项目介绍
1. 背景
IP地址是网络通信中的重要标识,通过分析IP地址的归属地信息,可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析:通过分析访问日志中的IP地址,了解网站访问者的地理位置分布和访问行为,优化网站内容和用户体验。
2. 需求
IP分析,返回归属地信息,要求在毫秒内完成。
3. 涉及技术栈
Eclipse的使用,JavaSE中面向对象,IO流,二分法查找,集合。
4. 目的
通过IP归属地查询项目,巩固javaSE部分所学知识,增强实战能力。
需具备以下能力:1.面向对象程序设计。
2.工具类的封装与使用。
3. 文件IO流操作。
4. 字符串处理。
5. 二分法查找。
二、主要思路
1. 读取提供的地址库文件,解析地址库字符串,转换为结构化数据
2. 封装对应的数据结构,进行查询。
3. 封装对应的相关工具类。
4. 对外提供接口,只需要入参和出参(入参:IP地址,出参:归属地)。
三、代码开发
创建utils包,存放工具类
创建pojo包,存放实体类
创建manager包,存储管理类,业务代码
创建controller包,存储程序入口类
1. 文件读取,封装为工具类
编写文件读取工具类,用于读取本地IP地址库文件中的数据。当前类放于Utils包下。
package com.zh.utils;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;public class FileReadUtil {// 默认编码方式private static String defaultencoding = "UTF-8";public static List<String> FileRead(String filePath, String encoding) throws IOException{// 通过类加载器获取流,防止打包后无法获取IP文件InputStream is = FileReadUtil.class.getClassLoader().getResourceAsStream(filePath);// 字节流// FileInputStream fis = new FileInputStream(filePath);// 转字符流Reader read = new InputStreamReader(is,encoding);// 缓冲流BufferedReader br = new BufferedReader(read);String temp = null;// 集合存储数据List<String> list = new ArrayList<String>();// 逐行读取while((temp = br.readLine()) != null) {list.add(temp);}br.close();return list;}// 提供无参的方法,以默认编码方式为参数,调用有参的方法public static List<String> FileRead(String filePath) throws IOException{return FileRead(filePath,defaultencoding);}}
2. 抽象Pojo类,用于数据结构化
根据地址库中的IP地址及其归属地的存储格式(1.0.0.0 1.0.0.255 澳大利亚 亚太互联网络信息中心),创建实体类。实体类属性包括IP起始地址,IP结束地址,归属地,IP起始地址的long类型数值,IP结束地址的long类型数值。IP地址转换为long类型,用于后续对IP地址进行排序。
实体类实现Comparable接口,用于自定义比较规则,覆写comparaTo方法,根据起始IP地址进行比较。
实体类实现Serializable接口,可对当前对象进行序列化操作。
package com.zh.pojo;import java.io.Serializable;import com.zh.utils.IPUtil;public class IPAndLocationPojo implements Comparable<IPAndLocationPojo>, Serializable {private static final long serialVersionUID = 1L;/*** 起始IP*/private String startIP;/*** 结束IP*/private String endIP;/*** 归属地*/private String location;/*** 起始地址转long类型*/private long startIPLong;/*** 结束地址转long类型*/private long endIPLong;public IPAndLocationPojo() {super();}public IPAndLocationPojo(String startIP, String endIP, String location) {super();this.startIP = startIP;this.endIP = endIP;this.location = location;this.startIPLong = IPUtil.ipToLong(startIP);this.endIPLong = IPUtil.ipToLong(endIP);}public String getStartIP() {return startIP;}public void setStartIP(String startIP) {this.startIP = startIP;}public String getEndIP() {return endIP;}public void setEndIP(String endIP) {this.endIP = endIP;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}public long getStartIPLong() {return startIPLong;}public long getEndIPLong() {return endIPLong;}@Overridepublic String toString() {return "IPAndLocationPojo [startIP=" + startIP + ", endIP=" + endIP + ", location=" + location+ ", startIPLong=" + startIPLong + ", endIPLong=" + endIPLong + "]";}@Overridepublic int compareTo(IPAndLocationPojo o) {long result = this.startIPLong - o.getStartIPLong();if(result > 0) {return 1; // 正序}else if(result < 0) {return -1; // 倒序}else {return 0;}}}
3. 结构化数据
调用文件读取工具类,返回一个集合,集合中的每一条数据,即为文件中的一行。
遍历集合,取出每一条数据,根据制表符(\t)分割,存储到数组中,此时数组中下标为0的位置存储的为IP起始地址的字符串,下标为1的位置存储的是IP结束地址的字符串,下标为2的位置存储的为归属地信息。
将数组中的数据封装为对象,后添加到ArrayList集合中,此时ArrayList中每一个元素即为一个IP归属地对象。
/*** 结构化数据* @param filePath* @param encoding* @return* @throws IOException*/public static List<IPAndLocationPojo> getPojoList(String filePath, String encoding) throws IOException{// 获取数据List<String> list = FileReadUtil.FileRead(filePath, encoding);// 封装结构化后的数据List<IPAndLocationPojo> pojoList = new ArrayList<IPAndLocationPojo>();// 逐条遍历取出数据for(String string : list) {// 跳过空行if(string == null || string.trim().equals("")) {continue;}// 分割字符串String[] strs = string.split("\t");// 跳过不合规的数组if(strs.length != 3) {continue;}String startIP = strs[0];String endIP = strs[1];String location = strs[2];IPAndLocationPojo ipPojo = new IPAndLocationPojo(startIP, endIP, location);pojoList.add(ipPojo);}return pojoList; }
4. 集合转数组并排序
由于实体类中存储的起始IP和结束IP为字符串类型,默认排序规则不符合要求,所以需要提供工具类,将实体类中起始IP地址和结束IP地址的字符串转换为long类型,为实体类中添加long类型的起始IP和结束IP,并实现Comparable接口,覆写comparaTo方法来自定义比较规则。
工具类:
package com.zh.utils;import java.util.Scanner;/*** Ip地址转换*/
public class IPUtil {/*** ip地址字符串转long类型* * @param ipString* @return*/public static long ipToLong(String ipString) {String[] str = ipString.split("\\.");return (Long.parseLong(str[0]) << 24) + (Long.parseLong(str[1]) << 16) + (Long.parseLong(str[2]) << 8)+ Long.parseLong(str[3]);}/*** long 类型数转Ip地址* * @param ipLong* @return*/public static String longToIP(long ipLong) {StringBuffer sb = new StringBuffer("");sb.append(String.valueOf(ipLong >> 24)).append(".").append(String.valueOf((ipLong & 0x00ffffff) >> 16)).append(".").append(String.valueOf((ipLong & 0x0000ffff) >> 8)).append(".").append(String.valueOf(ipLong & 0x000000ff));return sb.toString();}
}
/*** 将对象集合转换为数组并排序* @param ipPojoList* @return*/public static IPAndLocationPojo[] IpPojoArray(List<IPAndLocationPojo> ipPojoList) {// 集合转数组IPAndLocationPojo[] ipPojoArray = new IPAndLocationPojo[ipPojoList.size()];ipPojoList.toArray(ipPojoArray);// 数组排序Arrays.sort(ipPojoArray);return ipPojoArray;}
5. 二分法查找
根据用户输入的IP地址,采用二分法在已经排序好的数组中,查找IP的归属地信息。
由于IP地址库中存储的IP为一段地址范围,所以每次判断中间索引的起始地址小于用户输入地址后,需要在判断中间索引的结束地址是否大于用户输入IP,如果满足条件说明用户输入的IP地址位于当前中间索引起始地址所在的IP地址段,直接返回中间索引的IP归属地即为用户的IP归属地,
/*** 根据用户输入的地址查寻归属地* @param userIp* @param arr* @return*/public static String searchIP(String userIp, IPAndLocationPojo[] arr) {// 将用户输入的IP转换为long型long userIP = IPUtil.ipToLong(userIp);int height = arr.length - 1;int low = 0;// 二分查找while(low <= height) {int mid =(height + low) / 2;// 当中间索引的起始IP大于用户输入IP时,结束索引等于中间索引-1if(arr[mid].getStartIPLong() > userIP) {height = mid - 1;// 当中间索引的结束IP地址大于等于用户输入IP时,返回当前归属地信息}else if(arr[mid].getEndIPLong() >= userIP){ return arr[mid].getLocation();}else {low = mid + 1;}}return null; }
6. 封装接口类
封装接口,对外只提供获取归属地的方法,入参:IP地址, 出参:归属地
静态代码块中为数组中数据的初始化工作,保证每次执行只执行一次,不需要重复结构化数据,提高效率。文中代码对排序好的数组执行了序列化操作,也可以不进行序列化。
序列化工具类:
package com.zh.utils;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;public class FileSerializationUtil {// 序列化对象public static void SerializationObject(String path, Object arr) {try (FileOutputStream fos = new FileOutputStream(path);BufferedOutputStream bos = new BufferedOutputStream(fos);ObjectOutputStream oos = new ObjectOutputStream(bos);) {oos.writeObject(arr);oos.flush();} catch (Exception e) {e.printStackTrace();}}// 对象反序列化public static Object DeserializationObject(String path) {Object obj = null;try (FileInputStream fis = new FileInputStream(path);BufferedInputStream bis = new BufferedInputStream(fis);ObjectInputStream ois = new ObjectInputStream(bis);){obj = ois.readObject();} catch (Exception e) {e.printStackTrace();}return obj;}}
IP地址校验工具类:用于校验用户输入IP地址是否符合规范。
package com.zh.utils;import java.util.regex.Matcher;
import java.util.regex.Pattern;// IP地址校验
public class IPCheckUtil {// 正则表达式IP地址验证规则private static final String IP_PATTERN = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";// 创建匹配模式private static final Pattern pattern = Pattern.compile(IP_PATTERN);// 匹配IP地址public static boolean checkIP(String ipString) { Matcher matcher = pattern.matcher(ipString);return matcher.matches();}
}
管理类中代码对外提供接口的方法
private static final String IP_ILLEGAL = "IP地址不合法";private static final String SERIALIZED_FILE_PATH = "./serialized_ip_data.ser";private static IPAndLocationPojo[] arr = null;// 静态语句块只加载一次static {File serializedPath = new File(SERIALIZED_FILE_PATH);if(serializedPath.exists()) {arr = (IPAndLocationPojo[])FileSerializationUtil.DeserializationObject(SERIALIZED_FILE_PATH);}else {// 本地IP地址库String filePath = "ip_location_relation.txt";// 编码方式String encoding = "UTF-8";List<IPAndLocationPojo> list = null;try {// 数据结构化list = DataProcessManager.getPojoList(filePath, encoding);// 转换为数组并排序arr = DataProcessManager.IpPojoArray(list);FileSerializationUtil.SerializationObject(SERIALIZED_FILE_PATH, arr);} catch (IOException e) {e.printStackTrace();}}}/*** 获取IP归属地* @param ipString* @return* @throws IOException*/public static String ipLocationSer(String ipString){// 校验IP地址是否合法if (IPCheckUtil.checkIP(ipString)) {// IP地址合法,查询归属地String ipuser = DataProcessManager.searchIP(ipString, arr);return ipuser;} else {return IP_ILLEGAL;}}
7. 入口类
充当程序入口,执行main方法。
package com.zh.controller;import java.io.IOException;
import java.util.List;
import java.util.Scanner;import com.zh.manage.DataProcessManager;
import com.zh.pojo.IPAndLocationPojo;
import com.zh.utils.IPCheckUtil;//入口类
public class SystemController {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入要查询的IP地址:");String ip = null;while((ip = scanner.next())!= null) {// long startTime = System.currentTimeMillis();String location = DataProcessManager.ipLocationSer(ip);System.out.println(location);// System.out.println("耗时: " + (System.currentTimeMillis() - startTime));System.out.println("请输入要查询的IP地址:");}}
}
管理类完整代码:
package com.zh.manage;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import com.zh.pojo.IPAndLocationPojo;
import com.zh.utils.FileReadUtil;
import com.zh.utils.FileSerializationUtil;
import com.zh.utils.IPCheckUtil;
import com.zh.utils.IPUtil;/*** 管理类*/
public class DataProcessManager {private static final String IP_ILLEGAL = "IP地址不合法";private static final String SERIALIZED_FILE_PATH = "./serialized_ip_data.ser";private static IPAndLocationPojo[] arr = null;// 静态语句块只加载一次static {File serializedPath = new File(SERIALIZED_FILE_PATH);if(serializedPath.exists()) {arr = (IPAndLocationPojo[])FileSerializationUtil.DeserializationObject(SERIALIZED_FILE_PATH);}else {// 本地IP地址库String filePath = "ip_location_relation.txt";// 编码方式String encoding = "UTF-8";List<IPAndLocationPojo> list = null;try {// 数据结构化list = DataProcessManager.getPojoList(filePath, encoding);// 转换为数组并排序arr = DataProcessManager.IpPojoArray(list);FileSerializationUtil.SerializationObject(SERIALIZED_FILE_PATH, arr);} catch (IOException e) {e.printStackTrace();}}}/*** 获取IP归属地* @param ipString* @return* @throws IOException*/public static String ipLocationSer(String ipString){// 校验IP地址是否合法if (IPCheckUtil.checkIP(ipString)) {// IP地址合法,查询归属地String ipuser = DataProcessManager.searchIP(ipString, arr);return ipuser;} else {return IP_ILLEGAL;}}/*** 结构化数据* @param filePath* @param encoding* @return* @throws IOException*/private static List<IPAndLocationPojo> getPojoList(String filePath, String encoding) throws IOException{// 获取数据List<String> list = FileReadUtil.FileRead(filePath, encoding);// 封装结构化后的数据List<IPAndLocationPojo> pojoList = new ArrayList<IPAndLocationPojo>();// 逐条遍历取出数据for(String string : list) {// 跳过空行if(string == null || string.trim().equals("")) {continue;}// 分割字符串String[] strs = string.split("\t");// 跳过不合规的数组if(strs.length != 3) {continue;}String startIP = strs[0];String endIP = strs[1];String location = strs[2];IPAndLocationPojo ipPojo = new IPAndLocationPojo(startIP, endIP, location);pojoList.add(ipPojo);}return pojoList; }/*** 将对象集合转换为数组并排序* @param ipPojoList* @return*/private static IPAndLocationPojo[] IpPojoArray(List<IPAndLocationPojo> ipPojoList) {// 集合转数组IPAndLocationPojo[] ipPojoArray = new IPAndLocationPojo[ipPojoList.size()];ipPojoList.toArray(ipPojoArray);// 数组排序Arrays.sort(ipPojoArray);return ipPojoArray;}/*** 根据用户输入的地址查寻归属地* @param userIp* @param arr* @return*/private static String searchIP(String userIp, IPAndLocationPojo[] arr) {// 将用户输入的IP转换为long型long userIP = IPUtil.ipToLong(userIp);int height = arr.length - 1;int low = 0;// 二分查找while(low <= height) {int mid =(height + low) / 2;// 当中间索引的起始IP大于用户输入IP时,结束索引等于中间索引-1if(arr[mid].getStartIPLong() > userIP) {height = mid - 1;// 当中间索引的结束IP地址大于等于用户输入IP时,返回当前归属地信息}else if(arr[mid].getEndIPLong() >= userIP){ return arr[mid].getLocation();}else {low = mid + 1;}}return null; }}
运行结果:
8. 优化
为提高首次读取效率添加序列化和反序列化,pojo类中startIP和endIP属性无需序列化可添加transient关键字,可减小序列化后文件的大小,减少IO操作耗时。
/*** 起始IP*/private transient String startIP;/*** 结束IP*/private transient String endIP;
入口类方法可加入多线程,同步加载管理类,加载静态语句块,实现初始化。
//入口类
public class SystemController {public static void main(String[] args) {// 创建一个线程,加载管理类new Thread(() -> {try {Class.forName("com.zh.manage.DataProcessManager");} catch (ClassNotFoundException e) {e.printStackTrace();}}).start();// new Thread(() -> new DataProcessManager()).start();Scanner scanner = new Scanner(System.in);System.out.println("请输入要查询的IP地址:");String ip = null;while((ip = scanner.next())!= null) {long startTime = System.currentTimeMillis();String location = DataProcessManager.ipLocationSer(ip);System.out.println(location);System.out.println("耗时: " + (System.currentTimeMillis() - startTime));System.out.println("请输入要查询的IP地址:");}}
}
优化前首次查询耗时:
优化后首次查询耗时:
相关文章:

JavaSE-项目小结-IP归属地查询(本地IP地址库)
一、项目介绍 1. 背景 IP地址是网络通信中的重要标识,通过分析IP地址的归属地信息,可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析:通过分析访问日志中的IP地址,了解网站访问者的地理位置分…...

使用最大边界相关算法处理文章自动摘要
一、需求背景 对于博客或者文章来说,摘要是普遍性的需求。但是我们不可能让作者自己手动填写摘要或者直接暴力截取文章的部分段落作为摘要,这样既不符合逻辑又不具有代表性,那么,是否有相关的算法或者数学理论能够完成这个需求呢&…...

ref和reactive, toRefs的使用
看尤雨溪说:为什么Vue3 中应该使用 Ref 而不是 Reactive? toRefs import { ref, toRefs } from vue;// 定义一个响应式对象 const state ref({count: 0,name: Vue });// 使用toRefs转换为响应式引用对象 const reactiveState toRefs(state);// 现在你…...

从源代码看Chrome 版本号
一直以来都是用Chrome 浏览器,但是看到Chrome 点分4 组数据的表达方式,总是感觉怪怪的,遂深入源代码了解她的版本号具体表示的内容 chrome 浏览器中显示的版本号 源代码中的版本号标识 版本号文件位于 chrome/VERSION , 看到源代…...
Vue 图片加载失败处理
Vue 图片加载失败处理 很多人会使用 error 方法在图片加载 失败时替换img.src 的方式 但是这种方式在默认图片加载失败时,error会出现死循环,所以我使用了error v-if的方式。 <template><div><!-- 正常时显示 --><img v-if&quo…...

Quartus IP学习之ISSP(In-System Sources Probes)
一、ISSP IP概要: ISSP:In-System Sources & Probes Intel FPGA IP 作用: 分为In-System Sources与In-System Probesn-System Sources,输入端,等价于拨码开关,通过输入板载FPGA上的拨码开关状态改变…...
Vue组件通信讲解[父子组件通信]
Vue组件通信讲解 在Vue中,父子组件之间的通信可以通过props和emit来实现。props用于从父组件向子组件传递数据,而$emit用于从子组件向父组件触发事件。 以下是一个包含子传父和父传子通信的Vue案例解决方案: 父组件:Parent.vue…...

Qt应用开发(安卓篇)——调用ioctl、socket等C函数
一、前言 在 Qt for Android 中没办法像在嵌入式linux中一样直接使用 ioctl 等底层函数,这是因为因为 Android 平台的安全性和权限限制。 在 Android 中,访问设备硬件和系统资源需要特定的权限,并且需要通过 Android 系统提供的 API 来进行。…...
centos 安装docker CE
centos 安装docker CE 0. 参考 1. 安装需要的包 sudo yum install -y yum-utils \device-mapper-persistent-data \lvm22. 添加仓库 sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo3. 安装docker sudo yum install docke…...

某赛通电子文档安全管理系统 UploadFileList 任意文件读取漏洞复现
0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…...

Kafka运维相关知识
目录 一、基本概念 二、技术特性 三、设计思想 四、运维建议 一、基本概念 Apache kafka 是一个分布式的基于push-subscribe的消息系统,它具备快速、可扩展、可持久化的特点。它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于h…...
鸿蒙Native项目生产动态库(.so) 和静态库(.a)
通过 DevEco Studio 创建Native项目,我的版本为:Build Version: 3.1.0.501, built on June 20, 2023 CMakeLists.txt 文件中默认生成的是动态库,该命令为:add_library(entry SHARED hello.cpp) 通过Sutdio的操作 Build -> Bu…...

B站课程评分
Spring6 https://www.bilibili.com/video/BV1Ft4y1g7Fb/ 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错. mybatis https://www.bilibili.com/video/BV1JP4y1Z73S/?spm_id_from333.337.search-card.all.click 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错…...

【C++】拷贝构造函数和赋值运算符重载详解
目录 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 编辑前置和后置重载 ⭐拷贝构造函数 ⭐概念 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存 在的类类型对象创建新…...

BUUCTF-Real-[ThinkPHP]5-Rce
1、ThinkPHP检测工具 https://github.com/anx0ing/thinkphp_scan 漏洞检测 通过漏洞检测,我们发现存在rce漏洞! 2、漏洞利用 ---- [!] Name: Thinkphp5 5.0.22/5.1.29 Remote Code Execution VulnerabilityScript: thinkphp5022_5129.pyUrl: http://n…...
物联网中基于WIFI的室内温度检测系统设计
标题:物联网中基于WIFI的室内温度检测系统设计 摘要 随着物联网技术的快速发展,智能家居环境监测系统成为研究热点之一。本论文旨在设计并实现一个基于Wi-Fi的室内温度检测系统,用于实时监控和调节家庭或办公环境中的温度条件。该系统利用Wi-Fi信号的特性进行温度感知,不…...

驱动开发-系统移植
一、Linux系统移植概念 需要移植三部分东西,Uboot ,内核 ,根文件系统 (rootfs) ,这三个构成了一个完整的Linux系统。 把这三部分学明白,系统移植就懂点了。 二、Uboot 1、啥是Uboot uboot就是引导程…...
MySQL数据存储
MySQL数据存储 Innodb存储引擎的数据存储,可以使用两种方式进行存储:系统表空间和独立表空间 -- ON表示使用的是独立表空间-- OFF表示使用的是系统表空间show variables like %innodb_file_per_table% 系统表空间(共享表空间) 在MySQL5.5之前默认使用的是…...

带着问题读源码——Spring MVC是怎么找到接口实现类的?
引言 我们的产品主打金融服务领域,以B端客户为我们的核心合作伙伴,然而,我们的服务最终将惠及C端消费者。在技术实现上,我们采用了公司自主研发的微服务框架,该框架基于SpringBoot,旨在提供高效、可靠的服…...
[NAND Flash 7.1] 闪存系统性能优化方向集锦?AC timing? Cache? 多路并发?
依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< 传送门 >>> 总目录 主页: 元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言。 个人辛苦整理,付费内容,禁止转载。 内容摘要 优…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...