| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> IP归属地在线查询平台 -> 正文阅读 |
|
[网络协议]IP归属地在线查询平台 |
一、项目介绍1、背景根据IP得到位置,加标签 进行大数据分析,比如淘宝推荐等提供优质数据 ? ? ? ? ? ? ?www.ip.cn 等 查询IP 2、需求? ? ? IP 分析 归属地信息 , 查找在毫秒内完成 IP地址库,公网都是开放的 IANA : 国际组织,负责公网IP维护分发 3、技术栈Eclipse ,JavaSE中面向对象、IO流、二分法算法、Base64编码、工具类封装 4、目标? 通过开发IP地址归属地查询平台,我们需要对JavaSE综合技术有所提升,增强实战能力。学习完该项目我们应该具备如下能力: 1 面向对象程序设计 2 工具类封装与使用写法 3 文件IO流 4 字符串处理 5 二分法查找 6 IP地址的不同形式的使用 二、主要思路? ? ? ? 1 程序中读取内容 2 解析IP字符串,进行结构化处理 3 封装工具类 4 接口API ? ? ? ? ? 入参 : IP ? ? ? ? ? ?出参 : 归属地 应用开发类项目C/S结构,需要有特定的客户端,比如QQ,微信,eclipse Web开发类项目B/S结构为主.通过网页形式访问的在线系统,比如各类官网,各类管理系统等 中小型项目研发标准流程1 需求概述-需求描述:说清楚你为什么做这个项目 根据IP获取归属地 2 需求分析 : 根据需求概述,用技术角度考虑一下,是否可行 三方面 : 1 输入 , 2? 输出 , 3 必备物料(地址库) 输入 : 给定一个任意的合法IP地址 输出 : 返回IP地址对应的地址库 3 开发步骤 1 读取IP地址库 2 解析地址库的信息,进行结构化处理 3 将对象保存到list中 4 进行二分法查找,提高效率 5 对外提供访问的接口 6 测试 4 细节开发与风险控制 5 BUG修复,调优,标准化 6 正式上线 7 项目总结-项目复盘
? 2. 文本文件读取工具类抽象工具类 1 通过编码,实现输入与输出 2 抽象输入与输出,形成方法入参和出参 3 工具类代码实现并测试 2.1? 工具类编码?2.2? 工具类测试3.结构化?结构化 : 当我们知道第一个数据的格式的时候,那么第二个的数据格式就已经确定了,有规律可循,方便操作 根据非结构化数据,找到对应的规则,并创建对应的实体类进行封装,转换为结构化数 4.?抽象实体类并保存数据?4.1 实体类 ? 4.2? 拆分数据为三列 ? 5. 封装业务类DataProcessManager5.1? 封装数据集合 // 1 文件路径 ????????????????? String ipLibrayPath = "ip_location_relation.txt"; ????????????????? String encoding = "UTF-8"; ????????????????? // 保存数据对象 ????????????????? List<IPAndLocationPojo> ipAndLocationPojos = new ArrayList<IPAndLocationPojo>(); ????????????????? try { ????????????????????????? List<String> lineList = FileOperatorUtil.getLineList(ipLibrayPath, ??????????????????????????????????????????? encoding); ????????????????????????? for (String string : lineList) { ?????????????????????????????????? // 判断是否是空行 ?????????????????????????????????? if (string==null || string.trim().equals("")) { ??????????????????????????????????????????? continue; ?????????????????????????????????? } ?????????????????????????????????? // 分割为数组 ?????????????????????????????????? String[] columnArray = string.split("??????? "); ?????????????????????????????????? // 获取起始IP ?????????????????????????????????? String startIP = columnArray[0]; ?????????????????????????????????? // 获取结束IP ?????????????????????????????????? String endIP = columnArray[1]; ?????????????????????????????????? // 获取归属地 ?????????????????????????????????? String location = columnArray[2]; ?????????????????????????????????? // 封装到对象中 ?????????????????????????????????? IPAndLocationPojo ipAndLocationPojo = new IPAndLocationPojo(startIP, endIP, location); ?????????????????????????????????? // 添加到集合中 ?????????????????????????????????? ipAndLocationPojos.add(ipAndLocationPojo); ????????????????????????? } ????????????????????????? // 遍历测试 ????????????????????????? for (IPAndLocationPojo ip : ipAndLocationPojos) { ?????????????????????????????????? System.out.println(ip); ????????????????????????? } ????????????????? } catch (IOException e) { ????????????????????????? e.printStackTrace(); ????????????????? } 5.2 封装为管理类 public class DataProcessManager { ???????? /** ???????? ?* 结构化数据集合 ???????? ?* ???????? ?* @param filePath ???????? ?* @param encoding ???????? ?* @return ???????? ?* @throws IOException ???????? ?*/ ???????? public static List<IPAndLocationPojo> getPojoList(String filePath, ????????????????????????? String encoding) throws IOException { ????????????????? // 保存数据对象 ????????????????? List<IPAndLocationPojo> ipAndLocationPojos = new ArrayList<IPAndLocationPojo>(); ????????????????? List<String> lineList = FileOperatorUtil ?????????????????????????????????? .getLineList(filePath, encoding); ????????????????? for (String string : lineList) { ????????????????????????? // 判断是否是空行 ????????????????????????? if (string == null || string.trim().equals("")) { ?????????????????????????????????? continue; ????????????????????????? } ????????????????????????? // 分割为数组 ????????????????????????? String[] columnArray = string.split("??????? "); ????????????????????????? // 获取起始IP ????????????????????????? String startIP = columnArray[0]; ????????????????????????? // 获取结束IP ????????????????????????? String endIP = columnArray[1]; ????????????????????????? // 获取归属地 ????????????????????????? String location = columnArray[2]; ????????????????????????? // 封装到对象中 ????????????????????????? IPAndLocationPojo ipAndLocationPojo = new IPAndLocationPojo( ??????????????????????????????????????????? startIP, endIP, location); ????????????????????????? // 添加到集合中 ????????????????????????? ipAndLocationPojos.add(ipAndLocationPojo); ????????????????? } ????????????????? return ipAndLocationPojos; ???????? } } 5.3 测试封装类的方法 6.结构化集合转换为数组,toArray?public class TestListToArray_01 { ???????? public static void main(String[] args) { ????????????????? List<String> list = new ArrayList<String>(); ????????????????? list.add("a"); ????????????????? list.add("b"); ????????????????? list.add("c"); ????????????????? String[] strs = new String[list.size()]; ????????????????? list.toArray(strs); ????????????????? for (String string : strs) { ????????????????????????? System.out.println(string); ????????????????? } ????????????????? // 结构化数据集合转数组 ????????????????? // 1 文件路径 ????????????????? String ipLibrayPath = "ip_location_relation.txt"; ????????????????? String encoding = "UTF-8"; ????????????????? // 保存数据对象 ????????????????? try { ????????????????????????? List<IPAndLocationPojo> ipAndLocationPojos = DataProcessManager ??????????????????????????????????????????? .getPojoList(ipLibrayPath, encoding); ????????????????????????? IPAndLocationPojo[] ipAndLocationPojoArray = new IPAndLocationPojo[ipAndLocationPojos ??????????????????????????????????????????? .size()]; ????????????????????????? ipAndLocationPojos.toArray(ipAndLocationPojoArray); ????????????????????????? for (IPAndLocationPojo ipAndLocationPojo : ipAndLocationPojoArray) { ?????????????????????????????????? System.out.println(ipAndLocationPojo); ????????????????????????? } ????????????????? } catch (IOException e) { ????????????????????????? e.printStackTrace(); ????????????????? } ???????? } } 7.对象数组进行排序7.1 实现排序 1 自定义实现 冒泡排序 选择排序 2 工具类 Collections Arrays 一般不需要自己写,使用工具即可 7.2? 排序注意事项 被排序的对象必须具备可比性 1 实现Comparable接口 2 实现 Comparator接口 public class TestArraySort_01 { ???????? public static void main(String[] args) { ????????????????? // 基本类型 ????????????????? int[] intArray = { 10, 6, 8, 9, 3, 15 }; ????????????????? Arrays.sort(intArray); ????????????????? for (int i : intArray) { ????????????????????????? System.out.println(i); ????????????????? } ????????????????? // 引用类型 按照年龄升序 ????????????????? User[] users = { new User(18, "张三1"), new User(19, "张三2"), ?????????????????????????????????? new User(15, "张三3"), new User(17, "张三4") }; ????????????????? Arrays.sort(users); ????????????????? for (User user : users) { ????????????????????????? System.out.println(user); ????????????????? } ???????? } } class User implements Comparable<User> { ???????? private int age; ???????? private String name; ???????? public int getAge() { ????????????????? return age; ???????? } ???????? public void setAge(int age) { ????????????????? this.age = age; ???????? } ???????? public String getName() { ????????????????? return name; ???????? } ???????? public void setName(String name) { ????????????????? this.name = name; ???????? } ???????? public User(int age, String name) { ????????????????? super(); ????????????????? this.age = age; ????????????????? this.name = name; ???????? } ???????? public User() { ????????????????? super(); ???????? } ???????? @Override ???????? public String toString() { ????????????????? return "User [age=" + age + ", name=" + name + "]"; ???????? } ???????? @Override ???????? public int compareTo(User o) { ????????????????? // 返回大于0 往后放 ????????????????? // 返回小于0 往前放 ????????????????? // 返回0 相等 ????????????????? return this.age - o.age; ???????? } } 7.3? 业务问题 上面已经通过测试,解决了技术问题,下面就是业务问题 我们比较肯定是IP,我们的IP地址没有办法使用字符串进行比较,因为字符串比较的ASCII码进行比较的 比如 1.1.6.2 和 1.1.125.1 看上去 肯定是 125大于 6? 但是按ASCII码进行比较的话 是 6 大于 125 所以 我们需要把IP进行转换 public class IPUtil { ???????? public static void main(String[] args) { ????????????????? String ip = "126.56.78.59"; ????????????????? long ipLong = ipToLong(ip); ????????????????? System.out.println(ipLong); ????????????????? System.out.println(longToIP(ipLong)); ???????? } ???????? /** ???????? ?* 将127.0.0.1形式的IP地址转换成十进制整数,这里没有进行任何错误处理 ???????? ?* 通过左移位操作(<<)给每一段的数字加权,第一段的权为2的24次方,第二段的权为2的16次方,第三段的权为2的8次方,最后一段的权为1 ???????? ?*/ ???????? public static long ipToLong(String ipaddress) { ????????????????? long[] ip = new long[4]; ????????????????? // 先找到IP地址字符串中.的位置 ????????????????? int position1 = ipaddress.indexOf("."); ????????????????? int position2 = ipaddress.indexOf(".", position1 + 1); ????????????????? int position3 = ipaddress.indexOf(".", position2 + 1); ????????????????? // 将每个.之间的字符串转换成整型 ????????????????? ip[0] = Long.parseLong(ipaddress.substring(0, position1)); ????????????????? ip[1] = Long.parseLong(ipaddress.substring(position1 + 1, position2)); ????????????????? ip[2] = Long.parseLong(ipaddress.substring(position2 + 1, position3)); ????????????????? ip[3] = Long.parseLong(ipaddress.substring(position3 + 1)); ????????????????? return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; ???????? } ???????? /** ???????? ?* 将十进制整数形式转换成127.0.0.1形式的ip地址 将整数值进行右移位操作(>>>),右移24位,右移时高位补0,得到的数字即为第一段IP。 ???????? ?* 通过与操作符(&)将整数值的高8位设为0,再右移16位,得到的数字即为第二段IP。 ???????? ?* 通过与操作符吧整数值的高16位设为0,再右移8位,得到的数字即为第三段IP。 通过与操作符吧整数值的高24位设为0,得到的数字即为第四段IP。 ???????? ?*/ ???????? public static String longToIP(long ipaddress) { ????????????????? StringBuffer sb = new StringBuffer(""); ????????????????? // 直接右移24位 ????????????????? sb.append(String.valueOf((ipaddress >>> 24))); ????????????????? sb.append("."); ????????????????? // 将高8位置0,然后右移16位 ????????????????? sb.append(String.valueOf((ipaddress & 0x00FFFFFF) >>> 16)); ????????????????? sb.append("."); ????????????????? // 将高16位置0,然后右移8位 ????????????????? sb.append(String.valueOf((ipaddress & 0x0000FFFF) >>> 8)); ????????????????? sb.append("."); ????????????????? // 将高24位置0 ????????????????? sb.append(String.valueOf((ipaddress & 0x000000FF))); ????????????????? return sb.toString(); ???????? } } 7.4? ?实体类中衍生两个字段 上面可以把IP地址转换为long类型,方便进行排序比较 那么我们有起始IP和结束IP , 另外转换之后的长整型的值,也是需要保存起来的,和对应的IP字段需要一一对应 所以需要在对应的IP实体类中,再添加两个成员变量,分别保存转换之后的long值 ?通过构造方法对long类赋值 ?完整的实体类 public class IPAndLocationPojo implements Comparable<IPAndLocationPojo> { ???????? // 衍生字段,用于保存IP对应的long值 ???????? private long startIPLong; ???????? private long endIPLong; ???????? /** ???????? ?* 起始IP ???????? ?*/ ???????? private String startIP; ???????? /** ???????? ?* 结束IP ???????? ?*/ ???????? private String endIP; ???????? /** ???????? ?* 归属地 ???????? ?*/ ???????? private String location; ???????? @Override ???????? public int compareTo(IPAndLocationPojo o) { ????????????????? long status = this.startIPLong - o.startIPLong; ????????????????? // 不能强制转换 , 如果两个值相差 2147483647的话,转换为int之后 得到负数 ????????????????? // return (int) (this.startIPLong - o.startIPLong); ????????????????? return status > 0 ? 1 : 0; ???????? } ???????? public String getStartIP() { ????????????????? return startIP; ???????? } ???????? public long getStartIPLong() { ????????????????? return startIPLong; ???????? } ???????? public void setStartIPLong(long startIPLong) { ????????????????? this.startIPLong = startIPLong; ???????? } ???????? public long getEndIPLong() { ????????????????? return endIPLong; ???????? } ???????? public void setEndIPLong(long endIPLong) { ????????????????? this.endIPLong = endIPLong; ???????? } ???????? 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 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 IPAndLocationPojo() { ????????????????? super(); ???????? } ???????? @Override ???????? public String toString() { ????????????????? return "IPAndLocationPojo [startIP=" + startIP + ", endIP=" + endIP ?????????????????????????????????? + ", location=" + location + "]"; ???????? } } 7.5? 测试pojo排序 上面通过两个衍生字段已经让实体类拥有了排序功能,但是还没有进行排序 ?7.6 封装排序方法 ?7.7 测试 ?8.二分法查询上面已经把结构化数据进行排序,下一步就是二分法查询 // 1 确定起始和结束位置及中间位置 ????????????????? // 2 如果目标数据小于中间数据,起始位置不变,结束位置为 中间位置-1 , 重新生成中间位置 ????????????????? // 3 如果目标数据大于中间数据,结束位置不变,起始位置为 中间位置+1 , 重新生成中间位置 ????????????????? // 4 如果目标数据等于中间数据, 终止,中间位置则是对应的下标 ????????????????? // 5 如果起始位置 大于 结束位置 说明不存在 8.1? 基本类型 public class TestBinaraySearch_01 { ???????? public static void main(String[] args) { ????????????????? test1(); ???????? } ???????? public static void test1() { ????????????????? // 1 确定起始和结束位置及中间位置 ????????????????? // 2 如果目标数据小于中间数据,起始位置不变,结束位置为 中间位置-1 , 重新生成中间位置 ????????????????? // 3 如果目标数据大于中间数据,结束位置不变,起始位置为 中间位置+1 , 重新生成中间位置 ????????????????? // 4 如果目标数据等于中间数据, 终止,中间位置则是对应的下标 ????????????????? // 5 如果起始位置 大于 结束位置 说明不存在 ????????????????? int[] arr = { 1, 2, 3, 4, 7, 8, 9, 11, 15, 16, 18, 21, 26, 33, 55 }; ????????????????? int target = 19; ????????????????? int startIndex = 0; ????????????????? int endIndex = arr.length - 1; ????????????????? int m = (startIndex + endIndex) / 2; ????????????????? while (startIndex <= endIndex) { ????????????????????????? if (target == arr[m]) { ?????????????????????????????????? System.out.println(target + " 在 " + m + " 位上"); ?????????????????????????????????? return; ????????????????? ???????? } ????????????????????????? if (target < arr[m]) { ?????????????????????????????????? endIndex = m - 1; ????????????????????????? } else { ?????????????????????????????????? startIndex = m + 1; ????????????????????????? } ????????????????????????? m = (startIndex + endIndex) / 2; ????????????????? } ????????????????? System.out.println(target+" 不存在"); ???????? } } 8.2? 复杂类型 ?9.IP地址对象二分法9.1? 编码实现 public static void test3() throws IOException { ????????????????? // 1 文件路径 ????????????????? String ipLibrayPath = "ip_location_relation.txt"; ????????????????? String encoding = "UTF-8"; ????????????????? // 保存数据对象 ????????????????? List<IPAndLocationPojo> ipAndLocationPojos = DataProcessManager ?????????????????????????????????? .getPojoList(ipLibrayPath, encoding); ????????????????? // 转数组并排序 ????????????????? IPAndLocationPojo[] ipAndLocationPojoArray = DataProcessManager ?????????????????????????????????? .convertListToArraySort(ipAndLocationPojos); ????????????????? // 目标数据是IP ????????????????? String targetIP = "1226.44.58.127"; ????????????????? // 把IP转换为long ????????????????? long targetIPLong = IPUtil.ipToLong(targetIP); ????????????????? int startIndex = 0; ????????????????? int endIndex = ipAndLocationPojoArray.length - 1; ????????????????? int m = (startIndex + endIndex) / 2; ????????????????? /** ????????????????? ?* 如果 小于 起始IP? 找前面 ????????????????? ?* ????????????????? ?* 如果 大于 起始IP 找后面 ????????????????? ?* ????????????????? ?* 如果 大于等于起始IP且 小于等于 结束IP 则说明找到了 ????????????????? ?*/ ????????????????? while (startIndex <= endIndex) { ????????????????????????? if (targetIPLong >= ipAndLocationPojoArray[m].getStartIPLong() && targetIPLong <= ipAndLocationPojoArray[m].getEndIPLong()) { ?????????????????????????????????? System.out.println(targetIP + " 在 " + ipAndLocationPojoArray[m].getLocation()); ?????????????????????????????????? return; ????????????????????????? } ????????????????????????? if (targetIPLong < ipAndLocationPojoArray[m].getStartIPLong()) { ?????????????????????????????????? endIndex = m - 1; ????????????????????????? } else { ?????????????????????????????????? startIndex = m + 1; ????????????????????????? } ????????????????????????? m = (startIndex + endIndex) / 2; ????????????????? } ????????????????? System.out.println(targetIP + " 不存在"); ???????? } 9.2? 封装 public class DataProcessManager { ???????? /** ???????? ?* 二分法查找,入参是IP和数组,出参是对应的索引,找不到返回-1 ???????? ?* ???????? ?* @param ipAndLocationPojoArray ???????? ?* @param targetIP ???????? ?* @return ???????? ?* @throws IOException ???????? ?*/ ???????? public static int binaraySeach(IPAndLocationPojo[] ipAndLocationPojoArray, ????????????????????????? String targetIP) throws IOException { ????????????????? // 把IP转换为long ????????????????? long targetIPLong = IPUtil.ipToLong(targetIP); ????????????????? int startIndex = 0; ????????????????? int endIndex = ipAndLocationPojoArray.length - 1; ????????????????? int m = (startIndex + endIndex) / 2; ????????????????? /** ????????????????? ?* 如果 小于 起始IP 找前面 ????????????????? ?* ????????????????? ?* 如果 大于 起始IP 找后面 ????????????????? ?* ????????????????? ?* 如果 大于等于起始IP且 小于等于 结束IP 则说明找到了 ????????????????? ?*/ ????????????????? while (startIndex <= endIndex) { ????????????????????????? if (targetIPLong >= ipAndLocationPojoArray[m].getStartIPLong() ?????????????????????????????????????????? && targetIPLong <= ipAndLocationPojoArray[m].getEndIPLong()) { ?????????????????????????????????? return m; ????????????????????????? } ????????????????????????? if (targetIPLong < ipAndLocationPojoArray[m].getStartIPLong()) { ?????????????????????????????????? endIndex = m - 1; ????????????????????????? } else { ?????????????????????????????????? startIndex = m + 1; ????????????????????????? } ????????????????????????? m = (startIndex + endIndex) / 2; ????????????????? } ????????????????? return -1; ???????? } 9.3 测试 、 ?10? 工具类封装 10.1 编码 上面已经把二分法完成,已经可以实现功能了,测试代码就相当于客户端 但是客户端现在需要知道的数据还有点多,比如IP地址库文件名,比如字符编码等 这些都是客户无感的,客户只关心 IP和归属地,我把IP给你,你把归属地给我,就行了 所以此时 我们需要对外提供一个方法,只有入参和出参 public class DataProcessManager { ???????? /** ???????? ?* 对外提供的接口,入参是IP,出参是归属地 ???????? ?* ???????? ?* @param ip ???????? ?* @return ???????? ?*/ ???????? public static String getLocation(String ip) { ????????????????? // 1 文件路径 ????????????????? String ipLibrayPath = "ip_location_relation.txt"; ????????????????? String encoding = "UTF-8"; ????????????????? // 保存数据对象 ????????????????? List<IPAndLocationPojo> ipAndLocationPojos = null; ????????????????? IPAndLocationPojo[] ipAndLocationPojoArray = null; ????????????????? try { ????????????????????????? // 获取数据 ????????????????????????? ipAndLocationPojos = DataProcessManager.getPojoList(ipLibrayPath, ??????????????????????????????????????????? encoding); ????????????????????????? // 转数组并排序 ????????????????????????? ipAndLocationPojoArray = DataProcessManager ??????????????????????????????????????????? .convertListToArraySort(ipAndLocationPojos); ????????????????? } catch (IOException e) { ????????????????????????? e.printStackTrace(); ????????????????? } ????????????????? // 二分法查找 ????????????????? int index = DataProcessManager.binaraySeach(ipAndLocationPojoArray, ip); ????????????????? // 判断是否找到 ????????????????? if (index == -1) { ????????????????????????? return null; ????????????????? } else { ????????????????????????? return ipAndLocationPojoArray[index].getLocation(); ????????????????? } ???????? } 10.2 测试 ?10.3? 优化 现在getLocation方法,每次调用都会去读取IP地址库,并且转换为结构化数据,然后进行排序 这样效率很低,我们只需要让以上初始化工作在程序生命周期中只执行一次就可以 静态语句块 : 加载阶段执行,最先执行,且只执行一次 静态变量 : 静态变量的值再整个程序生命周期周有效 11. 入口类项目代码标准化之后,肯定要准备一个程序入口 ? ? ?12? 打包 1 普通jar包 : 不能独立运行,一般用于让其他程序引入调用的 2 可执行jar包 : 一般不会被引入 ? ? ? ?运行jar包 ? 把jar包和地址库放在同一目录下 然后CMD 进入该目录 执行命令 java?? -jar? xxx.jar? |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 10:03:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |