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博客 依公开知识及经验整理,如有误请留言。 个人辛苦整理,付费内容,禁止转载。 内容摘要 优…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
