【Java 数据结构】泛型
目录
一. 什么是泛型
二. 引出泛型
三. 泛型语法
四. 泛型的使用
五. 泛型是如何编译的
5.1 擦除机制
六. 泛型的继承
6.1 泛型类继承非泛型类
6.2 泛型类继承泛型类
6.2.1 父类的同名传递
6.2 2 父类的异名传递
6.2.3 父类固定类型传递
6.2.4 子类添加参数
七. 泛型的上界
7.1语法
7.2 示例
7.2.1 普通示例
7.2.2 复杂示例
八. 泛型方法
8.1 语法
8.2 非泛型类中的泛型方法
8.3 泛型类中的泛型方法
九. 通配符
9.1 通配符的上界
9.2 通配符的下界
9.3 通配符的限制
一. 什么是泛型
泛型是一种在编程语言中允许代码在定义时使用参数化类型的特性,它使得代码可以处理不同类型的数据,同时保持类型安全,提高代码的复用性和可维护性,比如在Java中可以通过泛型定义一个能存储任意类型数据的集合类。
二. 引出泛型
class MyArray{public Object[] arr=new Object[10];public Object getPos(int pos) {return arr[pos];}public void setArr(Object value,int pos){this.arr[pos]=value;}
}public class Test {public static void main(String[] args) {MyArray array =new MyArray();array.setArr(10,0);//父类的对象赋值给子类时,必须要强转Integer j=(Integer)array.getPos(0);System.out.println(j);}}
这样每次取出的值都要进行强制类型转化,不灵活,所以我们需要一个机制能帮助我们使得代码更灵活
三. 泛型语法
class 泛型类名称 < T >{
}
class 泛型类名称 < T ,E,K ....>{
}
注意:
- 这里的T相当于是个占位符 ,表示当前类是一个泛型类
- T也可与是其他的字母
四. 泛型的使用
注意:
- < >中传入的类型必须是引用/自定义数据类型,不能是基本数据类型
- 在实例化泛型类时,后面< >中可以不写(会发生类型推导)
- 泛型类还可以继承,下面会讲到
- 泛型的优点:数据类型参数化,编译时自动进行类型检查和转化
五. 泛型是如何编译的
5.1 擦除机制
泛型擦除是指在编译阶段,编译器会将泛型类型信息擦除,把泛型参数替换为其限定类型(通常是 Object 类型,如果有指定上限则替换为上限类型),并且在必要的地方插入类型转换以保持类型安全,还可以生成桥接方法以保持多态性,使得运行时的字节码中不再包含泛型的类型信息。
擦除前
public class MyArray <T>{public Object[] array=new Object[10];public void setArray(int pose,T value) {this.array[pose] = value;}public T getArray(int pos) {return (T)this.array[pos];}
}
擦除后
public class MyArray{public Object[] array=new Object[10];public void setArray(int pose,Object value) {this.array[pose] = value;}public Object getArray(int pos) {return this.array[pos];}
}
补充:为什么array数组不能写成泛型数组?
答:数组创建规则:在Java中,数组的创建必须使用具体的类型,例如 int[ ] ,String[ ]等,你不能使用泛型类型T[ ] 直接创建数组,因为编译器不知道 T 具体是什么类型,且因为泛型的擦除机制是在编译时发生的,运行时是没有泛型这个概念的
六. 泛型的继承
6.1 泛型类继承非泛型类
class A {public int i;public int getI() {return i;}
}public class B<T> extends A{public Object[] arr=new Object[10];public void func (int pos,T value){this.arr[pos] =value;}@Overridepublic int getI() {return super.getI();}
}
泛型类继承非泛型类时,重写父类的方法时,父类的方法签名不会改变,也不能将它改为泛型方法
6.2 泛型类继承泛型类
6.2.1 父类的同名传递
class A<T>{public T i;public T getI() {return i;}
}
public class B<T> extends A<T>{public Object[] arr=new Object[10];public void func (int pos,T value){this.arr[pos] =value;}@Overridepublic T getI() {return super.getI();}
}
6.2 2 父类的异名传递
class A<U>{public U i;public U getI() {return i;}
}
public class B<T> extends A<T>{public Object[] arr=new Object[10];public void func (int pos,T value){this.arr[pos] =value;}@Overridepublic T getI() {return super.getI();}
}
这里不是修改父类的定义,而是指定类型参数的对应关系,不影响父类的原始定义,只是子类使用时的类型绑定方式,并且编译后会被类型消除,运行时没有区别(编译器理解U)
6.2.3 父类固定类型传递
class A<U>{public U i;public U getI() {return i;}
}
public class B<T> extends A<String>{public Object[] arr=new Object[10];public void func (int pos,T value){this.arr[pos] =value;}@Overridepublic String getI() {return super.getI();}
}
//编译时生成的桥接方法public Object getI() {getI();}
这是实际上是泛型的桥接方法(为什么重写父类后的方法签名不一致却也能构成重写),下面是关于桥接方法的具体介绍:
在子类重写泛型父类的方法时,尽管在源代码中可以明确地指定重写方法的返回类型为具体的类型参数(如 SubGenericClass 中 getValue 方法返回 Integer ),但由于类型擦除,在字节码层面父类的方法签名会变为返回 Object 类型。为了保证多态性,即根据对象的实际类型来正确调用重写后的方法,就需要桥接方法来进行中间转换。
桥接方法的工作方式
编译器会在子类中生成桥接方法,其方法签名与父类被擦除后的方法签名一致(返回类型为擦除后的类型)。在桥接方法内部,会调用子类中实际重写的方法。如前面例子中, SubGenericClass 的桥接方法 public Object getValue() 会调用子类真正的 public Integer getValue() 方法,这样在运行时,无论通过父类引用还是子类引用调用 getValue 方法,都能正确地根据对象的实际类型来执行子类重写后的方法,实现多态性
6.2.4 子类添加参数
class A<U>{public U i;public U getI() {return i;}
}
public class B<T,K> extends A<T>{public K m;public Object[] arr=new Object[10];public void func (int pos,T value){this.arr[pos] =value;}public K func2(){return m;}@Overridepublic T getI() {return super.getI();}
}
总结:
- 在泛型子类继承泛型父类在签名时,父类的泛型参数要与子类泛型参数的其中一个参数名相同(子类必须为父类的每个参数提供类型),也可以给父类指定具体类型
- 在Java中,会根据子类的参数传递给父类参数,在继承的关系中父类参数的具体类型由子类决定
七. 泛型的上界
泛型的上界是在定义泛型类型时,对泛型参数的类型进行限制,指定其必须是某个类或接口的子类或实现类。
7.1语法
class 泛型类名称 <类型形参 extends 类型边界>{
......
}
7.2 示例
7.2.1 普通示例
7.2.2 复杂示例
类型边界也可以是接口,表示只有实现了该接口的类型才能传入该参数
class 泛型类名称 <类型形参 extends 接口>{
......
}
小测试:写一个泛型类,在其中定义一个方法来求任意类型数组的最大值
public class A <T extends Comparable<T>>{public T Max(T[] arr){T max=arr[0];for (int i = 0; i < arr.length; i++) {if(arr[i].compareTo(max)>0){max=arr[i];}}return max;}}class test {public static void main(String[] args) {Integer[] arr=new Integer[]{1,24,26,75,35,56};A<Integer> a=new A<>();Integer m=a.Max(arr);System.out.println(m);}
}
注意:
- 传入的类型必须是类型边界的子类或者类型边界本身,如果extends后面是接口的话,传入的参数类型必须是实现了该接口的类
- 如果没有指定类型边界则默认为object类
- 泛型没有下界
八. 泛型方法
泛型方法是Java中一种允许在方法中使用泛型类型参数的特性。它可以使方法更具通用性,能够处理不同类型的数据,而不需要为每种数据类型都编写重复的代码。
8.1 语法
方法限定符 <类型形参列表> 返回值类型方法名称(形参列表) {
...
}
8.2 非泛型类中的泛型方法
public class A {public <T> T func(T i){return i;}public static <T> T func(){return null;}public static void main(String[] args) {A a=new A();Integer i=10;Integer b= a.func(i);//类型推导Integer c= a.<Integer>func(i);//非类型推导Integer m=A.<Integer>func();//非类型推导}
}
注意:
- 泛型方法会根据你传入的参数来进行类型推导,推导出第一个<T>中的类型形参
- 如果是无参数的泛型方法就必须要在调用时显式指定类型
8.3 泛型类中的泛型方法
class GenericClass<T> {private T data;public GenericClass(T data) {this.data = data;}// 泛型方法也定义了T作为类型参数,这里会隐藏类的Tpublic <T> void printType(T item) {System.out.println("方法中的T类型: " + item.getClass().getName());// 这里的data是类的成员变量,类型是类定义的TSystem.out.println("类中的T类型: " + data.getClass().getName());}
}public class Main {public static void main(String[] args) {GenericClass<Integer> generic = new GenericClass<>(10);generic.printType("Hello");}
}
注意:
- 当泛型类的参数类型名与泛型方法名一致时,泛型方法会隐藏泛型类的参数类型,即泛型方法中的T是在调用方法时传入的类型参数,而不是泛型类的参数类型
- 为了避免混淆,泛型方法的参数类型名尽量与泛型类的参数类型名不同
九. 通配符
在Java泛型中,通配符 ?是一种用于表示不确定类型的特殊语法,它使得泛型代码更加灵活和通用
9.1 通配符的上界
<? extends 上界>
传入的数据类型必须是上界本身或者上界的子类
import java.util.ArrayList;
import java.util.List;class Animal {}
class Cat extends Animal {}
class Dog extends Animal {}public class UpperBoundWildcardExample {public static double calculateTotalWeight(List<? extends Animal> animals) {double totalWeight = 0.0;// 假设每个动物都有weight属性,这里简单模拟for (Animal animal : animals) {// 可以安全地读取Animal及其子类对象,因为上界是AnimaltotalWeight += 1.0; }return totalWeight;}public static void main(String[] args) {List<Cat> catList = new ArrayList<>();catList.add(new Cat());List<Dog> dogList = new ArrayList<>();dogList.add(new Dog());double catTotalWeight = calculateTotalWeight(catList);double dogTotalWeight = calculateTotalWeight(dogList);System.out.println("猫的总重量: " + catTotalWeight);System.out.println("狗的总重量: " + dogTotalWeight);}
}
注意:使用了通配符的上界,就只能读取数据,不能写入数据,因为我们不能保证传入的是那种参数类型(是上界本身还是上界的子类是不确定的),只要使用了?,编译器在编译时的定义是模糊的(即使传入的是具体的参数类型)
9.2 通配符的下界
<? super 下界>
传入的数据类型必须是上界本身或者上界的父类
import java.util.ArrayList;
import java.util.List;class Fruit {}
class Apple extends Fruit {}
class RedApple extends Apple {}public class LowerBoundWildcardExample {public static void addApple(List<? super Apple> fruitList) {Apple apple = new Apple();// 可以安全地添加Apple及其子类对象到列表中fruitList.add(apple); RedApple redApple = new RedApple();fruitList.add(redApple); }public static void main(String[] args) {List<Apple> appleList = new ArrayList<>();List<Fruit> fruitList = new ArrayList<>();addApple(appleList);addApple(fruitList);System.out.println("苹果列表: " + appleList);System.out.println("水果列表: " + fruitList);}
}
注意:使用了通配符的上界,就只能写入数据,不能读取数据,但是写入数据只能写入下界的子类对象,因为我们不能保证传入的是那种参数类型
9.3 通配符的限制
- 不能用于定义泛型类或方法:
通配符只能在方法的参数、局部变量或表达式中使用,不能用于定义泛型类、泛型接口或泛型方法的类型参数。例如, class MyClass<?> 是不合法的定义。
- 不能直接实例化通配符类型:
List<?> list = new ArrayList<?>(); // 编译错误
List<? extends Number> numbers = new ArrayList<? extends Number>(); // 编译错误List<?> list = new ArrayList<String>(); // 合法
List<? extends Number> numbers = new ArrayList<Integer>(); // 合法
- 方法调用限制:
只是可以调用与元素类型无关的通用方法
List<?> list = new ArrayList<String>();// ✅ 可以调用的方法(不依赖元素类型):list.size(); // 获取大小list.isEmpty(); // 判断空list.clear(); // 清空集合Iterator<?> it = list.iterator(); // 获取迭代器// ❌ 不能调用的方法(依赖元素类型):list.add("hello"); // 编译错误list.add(new Object()); // 编译错误list.remove("hello"); // 编译错误(但实际可以调用,特殊例外)
- 类型引用限制:
不能直接引用通配符类型,?只能存在于<>中
class MyClass<?> { ... } // 编译错误
? myVariable; // 编译错误
- 数组创建限制:
List<?>[] array = new List<?>[10]; // 编译错误
相关文章:
【Java 数据结构】泛型
目录 一. 什么是泛型 二. 引出泛型 三. 泛型语法 四. 泛型的使用 五. 泛型是如何编译的 5.1 擦除机制 六. 泛型的继承 6.1 泛型类继承非泛型类 6.2 泛型类继承泛型类 6.2.1 父类的同名传递 6.2 2 父类的异名传递 6.2.3 父类固定类型传递 6.2.4 子类添加参数 七. 泛…...
鲲鹏麒麟搭建Docker仓库
Docker Registry简介 Docker Registry是一个开源的镜像仓库工具,用于存储和分发Docker镜像。它是Docker生态系统中的核心组件之一,提供了镜像的推送(push)、拉取(pull)和管理功能。 主要特性: 1、开源免费:Apache 2.0许可证 2、轻…...
Java快速上手之实验4(接口回调)
1.编写接口程序RunTest.java,通过接口回调实现多态性。解释【代码4】和【代码6】的执行结果为何不同? interface Runable{ void run(); } class Cat implements Runable{ public void run(){ System.out.println("猫急上树.."…...
【前端】【业务场景】【面试】在前端开发中,如何实现实时数据更新,比如实时显示服务器推送的消息,并且保证在不同网络环境下的稳定性和性能?
问题:在前端开发中,如何实现实时数据更新,比如实时显示服务器推送的消息,并且保证在不同网络环境下的稳定性和性能? 一、实现实时数据更新的方法 WebSocket: 原理:WebSocket 是一种在单个 TCP …...
redis相关问题整理
Redis 支持多种数据类型: 字符串 示例:存储用户信息 // 假设我们使用 redis-plus-plus 客户端库 auto redis Redis("tcp://127.0.0.1:6379"); redis.set("user:1000", "{name: John Doe, email: john.doeexample.com}"…...
某城乡老旧房屋试点自动化监测服务项目
1. 项目简介 我国是房屋建设增长量最高的国家或地区,但上个世纪末建造的房屋多为砖混结构,使用寿命短且缺乏维护。这些房屋在使用过程中受到地质活动、自然环境和人为改造的影响,其结构强度逐年下降,部分房屋甚至出现墙体裂缝、倾…...
企业为何要求禁用缺省口令?安全风险及应对措施分析
在当今数字化时代,企业网络安全面临着前所未有的挑战。缺省口令的使用是网络安全中的一个重要隐患,许多企业在制定网络安全红线时,明确要求禁用缺省口令。本文将探讨这一要求的原因及其对企业安全的重要性。 引言:一个真实的入侵场…...
在 MySQL 中,索引前缀长度为什么选择为 191
在 MySQL 中,索引前缀长度选择为 191 的常见原因主要与 字符集编码 和 索引长度限制 相关,具体解释如下: 1. 字符集编码的影响 utf8mb4 字符集: MySQL 的 utf8mb4 字符集每个字符最多占用 4 个字节(相比 utf8 的 3 字…...
【Python语言基础】24、并发编程
文章目录 1. 多线程(threading模块)1.1 多线程的实现(threading 模块)1.2 多线程的优缺点1.3 线程同步与锁 2. 多进程(multiprocessing模块)2.1 多进程实现(multiprocessing模块)2.2 多进程的优缺点2.3 进程…...
MySQL-自定义函数
自定义函数 函数的作用 mysql数据库中已经提供了内置的函数,比如:sum,avg,concat等等,方便我们日常的使用,当需要时mysql支持定义自定义的函数,方便与我们对于需用复用的功能进行封装。 基本…...
实时操作系统在服务型机器人中的关键作用
一、服务型机器人的发展现状与需求 近年来,服务型机器人市场呈现出蓬勃发展的态势。据国际机器人联合会(IFR)2024 年度报告显示,全球人形机器人市场规模预计在 2025 年达到 38.7 亿美元,年复合增长率达 19.2%。服务型机…...
智能电网第5期 | 老旧电力设备智能化改造:协议转换与边缘计算
随着电力行业数字化转型加速,大量在役老旧设备面临智能化升级需求。在配电自动化改造过程中,企业面临三大核心挑战: 协议兼容难题:传统设备采用Modbus等老旧协议,无法接入智能电网系统 数据处理瓶颈:设备本…...
【UML建模】starUML工具
一.概述 StarUML是一款UML工具,允许用户创建和管理UML(统一建模语言)模型,广泛应用于软件工程领域。它的主要功能包括创建各种UML图:如用例图、类图、序列图等,支持代码生成与反向工程,以及提供…...
【技术笔记】Cadence实现Orcad与Allegro软件交互式布局设置
【技术笔记】Cadence实现Orcad与Allegro软件交互式布局设置 更多内容见专栏:【硬件设计遇到了不少问题】、【Cadence从原理图到PCB设计】 在做硬件pcb设计的时候,原理图选中一个元器件,希望可以再PCB中可以直接选中。 为了达到原理图和PCB两两…...
第十七届山东省职业院校技能大赛 中职组网络建设与运维赛项
第十七届山东省职业院校技能大赛 中职组网络建设与运维赛项 赛题 B 卷 第十七届山东省职业院校技能大赛中职组网络建设与运维赛项 1 赛题说明 一、竞赛项目简介 “网络建设与运维”竞赛共分为以下三个模块: 网络理论测试; 网络建设与调试…...
深入详解人工智能数学基础——概率论中的KL散度在变分自编码器中的应用
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
Docker配置DNS方法详解及快速下载image方法
根据错误信息,Docker 在拉取镜像时遇到网络连接超时(Client.Timeout exceeded),通常与 代理配置错误、DNS 解析失败、镜像源访问受限 或 网络防火墙限制 有关。以下是详细解决方案: 1. 检查并修复代理配置 如果你使用了 HTTP 代理: 确认代理地址是否有效(替换 speed.ip…...
Rundeck 介绍及安装:自动化调度与执行工具
Rundeck介绍 概述:Rundeck 是什么? Rundeck 是一款开源的自动化调度和任务执行工具,专为运维场景设计,帮助工程师通过统一的平台管理和执行跨系统、跨节点的任务。它由 PagerDuty 维护(2016 年收购)&#…...
济南国网数字化培训班学习笔记-第二组-6-输电线路现场教学
输电线路现场教学 杆塔组装 角钢塔 角钢-连扳-螺栓 螺栓(M): 脚钉-螺栓(螺栓头-无扣长-螺纹-螺帽)-垫片-螺帽/防盗帽/防松帽M20*45 表示直径20mm,长度45mm螺栓级别由一个类似浮点数表示,如…...
数据结构——二叉树,堆
目录 1.树 1.1树的概念 1.2树的结构 2.二叉树 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 2.4.1顺序结构 2.4.2链式结构 3.堆 3.1堆的概念 3.2堆的分类 3.3堆的实现 3.3.1初始化 3.3.2堆的构建 3.3.3堆的销毁 3.3.4堆的插入 3.3.5…...
PostgreSQL 分区表——范围分区SQL实践
PostgreSQL 分区表——范围分区SQL实践 1、环境准备1-1、新增原始表1-2、执行脚本新增2400w行1-3、创建pg分区表-分区键为创建时间1-4、创建24年所有分区1-5、设置默认分区(兜底用)1-6、迁移数据1-7、创建分区表索引 2、SQL增删改查测试2-1、查询速度对比…...
第八节:进阶特性高频题-Pinia与Vuex对比
优势:无嵌套模块、Composition API友好、TypeScript原生支持 核心概念:state、getters、actions(移除mutation) 深度对比 Pinia 与 Vuex:新一代状态管理方案的核心差异 一、核心架构设计对比 维度VuexPinia设计目标集…...
路由交换网络专题 | 第七章 | BGP练习 | 次优路径 | Route-Policy | BGP认证
基本部分配置讲解: 配置BGP相关部分: // BGP区域配置: 用作环回口创建BGP对等体// “ipv4-family unicast”是指进入BGP的IPv4单播地址族视图。 // 配置完后仅仅只在IPV4地址簇下建立对等体。* [AR3]bgp 100 [AR3-bgp]peer 1.1.1.1 as-number 100 [AR…...
序论文42 | patch+MLP用于长序列预测
论文标题:Unlocking the Power of Patch: Patch-Based MLP for Long-Term Time Series Forecasting 论文链接:https://arxiv.org/abs/2405.13575v3 代码链接:https://github.com/TangPeiwang/PatchMLP (后台回复“交流”加入讨…...
【mongodb】系统保留的数据库名
目录 1. admin2. config3. local4. test(非严格保留,但常作为默认测试数据库)5. 注意事项6. 其他相关说明 1. admin 1.用途:用于存储数据库的权限和用户管理相关数据。2.特点:该数据库是 MongoDB 的超级用户数据库&am…...
js 的call 和apply方法用处
主要用于ECMAScript与宿主环境(文档对象(DOM)、浏览器对象(BOM))的交互中; 例子:function changeStyle(attr, value){ this.style[attr] value; } …...
济南国网数字化培训班学习笔记-第二组-2节-输电线路施工及质量
输电线路施工及质量 质量管控基本规定 基本规定 项目分类 土石方(测量挖坑)、基础、杆塔、架线、接地、线路防护 检验项目分类原则: 1.主控项目:影响工程性能、强度、安全性和可靠性,且不易修复和处理 2.一般项…...
“Daz to Unreal”将 G8 角色(包括表情)从 daz3d 导入到 UE5。在 UE5 中,我发现使用某个表情并与闭眼混合后,上眼睑出现了问题
1) Bake & Export Corrective Morphs from Daz before you go into UE5 1) 在进入 UE5 之前,从 Daz 烘焙并导出修正型变形 In Daz Studio 在 Daz Studio 中 Load your G8 head, dial in the exact mix (e.g. Smile 1.0 Eyes Closed 1.0). 加载你的 G8 头部&am…...
Linux系统之----进程优先级、调度与切换
在开启本篇文章的学习之前,我们先要熟悉如下两个事 1.概念 进程优先级指的是进程能得到某种资源的先后顺序,要理解好它与权限的关系,优先级是 能,拥有资源的先后顺序,权限是 能还是不能的问题 2.为什么要有优先级…...
Web3钱包开发功能部署设计
Web3钱包开发功能部署设计全景指南(2025技术架构与实战) ——从核心模块到多链生态的完整解决方案 一、核心功能模块设计 1.1 资产管理体系 Web3钱包的核心功能围绕资产存储、交易验证、多链兼容展开: • 密钥管理:…...
【含文档+PPT+源码】基于SpringBoot的开放实验管理平台设计与实现
项目介绍 本课程演示的是一款基于SpringBoot的开放实验管理平台设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...
小刚说C语言刷题——1317正多边形每个内角的度数?
1.题目描述 根据多边形内角和定理,正多边形内角和等于:( n-2 ) 180∘ ( n 大于等于 3且 n 为整数) 请根据正多边形的边数,计算该正多边形每个内角的度数。(结果保留1位小数&#x…...
Spring—AOP
AOP是在不惊动原有的代码的基础上对功能进行增强操作 连接点:JoinPoint,可以被AOP控制的方法 通知:Advice,增强的逻辑,共性功能 切入点:PointCut,匹配连接点的条件,表明连接点中哪…...
算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II、区间和
209.长度最小的子数组 题目 思路与解法 **第一想法:**无 carl的讲解: 滑动窗口 class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:ij0lens len(nums)sum 0res lens 1while j < lens:# for m in range(i, j1)…...
【C++ 真题】P3456 [POI2007] GRZ-Ridges and Valleys
[POI2007] GRZ-Ridges and Valleys 题面翻译 题目描述 译自 POI 2007 Stage 2. Day 0「Ridges and Valleys」 给定一个 n n n \times n nn 的网格状地图,每个方格 ( i , j ) (i,j) (i,j) 有一个高度 w i j w_{ij} wij。如果两个方格有公共顶点,…...
Vue3 中 computed的详细用法
Vue 3 中 computed 是一个非常重要的响应式 API,它是基于其依赖项的值来计算得出的值,当依赖项发生变化时,计算属性会自动更新 基本用法 在选项式 API 中,computed 通常作为一个选项直接在组件的选项对象中定义。例如 <temp…...
位带和位带别名区
位带区域和位带别名区域 位带区域(Bit-banding)是一种技术, 允许开发者直接访问和修改内存中的单个位。 这种技术在某些微控制器(如ARM Cortex-M系列)中特别有用,因为它可以简化对寄存器位的访问和修改。 …...
DRF凭什么更高效?Django原生API与DRF框架开发对比解析
一、原生 Django 开发 API 的局限性 虽然 Django 可以通过 JsonResponse 和视图函数手动构建 API,但存在以下问题: 手动序列化与反序列化 需要手动将模型实例转换为 JSON,处理复杂数据类型(如嵌套关系)时代码冗长且易…...
Agent智能体应用详解:从理论到实践的技术探索
一、Agent智能体是什么? 1. 核心定义 Agent智能体是能够感知环境、自主决策并执行动作以实现目标的软件实体。其核心特征包括: 自主性:无需外部指令持续运行。 反应性:实时响应环境变化。 目标导向:基于预设或学习…...
Windows下使用 VS Code + g++ 开发 Qt GUI 项目的完整指南
🚀 使用 VS Code g 开发 Qt GUI 项目的完整指南(Windows MSYS2) 本指南帮助你在 Windows 下使用 VS Code g CMake Qt6 快速搭建 Qt GUI 项目,适合熟悉 Visual Studio 的开发者向跨平台 VS Code 工具链迁移。 🛠️…...
arm64适配系列文章-第三章-arm64环境上mariadb的部署
ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...
YOLOv8融合CPA-Enhancer【提高恶略天气的退化图像检测】
1.CPA介绍 CPA-Enhancer通过链式思考提示机制实现了对未知退化条件下图像的自适应增强,显著提升了物体检测性能。其插件式设计便于集成到现有检测框架中,并在物体检测及其他视觉任务中设立了新的性能标准,展现了广泛的应用潜力。 关于CPA-E…...
编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)
前言 在使用终端编译 C 程序时,报错: 或类似提示,意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g,适用于新手或 C 入门阶段的你。 什么是 g? g 是 GN…...
Spring 过滤器详解:从基础到实战应用
Spring 过滤器详解:从基础到实战应用 引言 在 Spring 框架中,过滤器(Filter)是处理 HTTP 请求和响应的重要组件。它们为开发者提供了一种在请求到达控制器之前或响应返回客户端之前进行操作的机制。本文将深入探讨 Spring 中常见…...
达梦并行收集统计信息
达梦收集统计信息速度如何? 答:1分钟1G 大库收集起来可能比较慢,想并行收集需要一些条件 3个参数先了解一下 我把max_parallel_degree改为16 相关说明可以看一下 对一个3G的表收集 收集方法 DBMS_STATS.GATHER_TABLE_STATS( TEST,T1,…...
AOSP CachedAppOptimizer 冻结方案
背景 Android 一直面临一个核心难题:如何优化进程对有限系统资源(如 CPU、电量)的使用,同时保证用户体验。 当进程进入后台后,它们虽不再贡献用户体验,却仍可能消耗资源。传统的杀后台方案虽然节省资源&a…...
JVM-类加载机制
类加载 前言:为什么需要了解类加载?什么是类加载?生命周期概览类加载过程详解3.1 加载 (Loading)3.2 连接 (Linking)3.2.1 验证 (Verification)3.2.2 准备 (Preparation)3.2.3 解析 (Resolution) 3.3 初始化 (Initialization)3.3.1 <clini…...
【小白福音】SFTP限制权限登录
下面以在 Linux 环境(例如 Ubuntu 或 CentOS)上配置 SFTP chroot 为例,给出详细的步骤说明。即使你不熟悉服务器运维,也可以按照以下步骤进行配置,保证指定的 SFTP 用户只能访问预设目录,而无法触碰其他文件。 目录 一、配置SFTP权限1. 创建专用 SFTP 用户和用户组2. 搭建…...
海量数据笔试题--Top K 高频词汇统计
问题描述: 假设你有一个非常大的文本文件(例如,100GB),文件内容是按行存储的单词(或其他字符串,如 URL、搜索查询词等),单词之间可能由空格或换行符分隔。由于文件巨大&…...
Postman设置环境变量与Token
设置环境变量 设置某个Collection下的变量...