Kotlin基础(八):泛型
前言
本文主要讲解kotlin泛型,主要包括泛型基础,类型变异,类型投射,星号投射,泛型函数,泛型约束,泛型在Android中的使用。
Kotlin文章列表
Kotlin文章列表: 点击此处跳转查看
目录
1.1 泛型基础
在 Kotlin 中,泛型是一种类型参数化的机制,它允许我们编写具有通用性的代码。使用泛型,我们可以编写可以在不同类型上工作的代码,而无需为每个具体类型编写重复的代码。
Kotlin 中的泛型使用尖括号 < >
来定义,并且在类型声明中使用角括号来指定类型参数。例如,下面是一个简单的泛型函数的例子:
fun <T> printItem(item: T) {println(item.toString())
}
在这个例子中,<T>
表示这个函数是一个泛型函数,并且 T
是一个类型参数。我们可以在函数内部使用 T
来表示任意类型。在调用 printItem
函数时,编译器会根据实参的类型推断出 T
的具体类型。
下面是一个使用泛型的类的例子:
class Box<T>(val item: T) {fun getItem(): T {return item}
}fun main() {val box = Box("Hello")val item: String = box.getItem()println(item)
}
在这个例子中,Box
类使用泛型类型参数 T
,并且有一个泛型函数 getItem
返回类型为 T
。在 main
函数中,我们创建了一个 Box<String>
对象,并调用了 getItem
函数来获取其中的值。
除了单个类型参数外,Kotlin 还支持多个类型参数的泛型定义。例如:
class Pair<A, B>(val first: A, val second: B) {// ...
}
在使用泛型时,我们可以限制类型参数的上界。这可以通过使用冒号 :
加上类型约束来实现。例如,我们可以指定一个类型参数必须是某个类的子类,或者实现了某个接口。下面是一个使用类型约束的例子:
fun <T : Number> convertToInt(value: T): Int {return value.toInt()
}
在这个例子中,<T : Number>
指定了类型参数 T
必须是 Number
类的子类。这样,我们可以在函数体内调用 Number
类的方法,例如 toInt
。
这些是 Kotlin 中泛型的基础知识。通过使用泛型,我们可以编写更具有通用性和复用性的代码,提高代码的灵活性和可读性。
1.2 类型变异
在 Kotlin 中,类型变异(Type Variance)是指在泛型类型中允许子类型关系的灵活性。Kotlin 提供了几种类型变异的修饰符,用于在使用泛型时指定类型参数的变异方式。这些修饰符包括:in
、out
和默认(不使用修饰符)。
-
in
:逆变(Contravariant)
使用in
修饰符声明的类型参数只能用作输入(即参数类型),不能用作输出(即返回类型)。它允许我们使用指定的类型参数的超类作为泛型类型的实参。在函数中,逆变类型参数只能作为方法的参数类型。例如,考虑一个逆变的接口
Comparable
:interface Comparable<in T> {fun compare(other: T): Int }
这里的
in
修饰符表示类型参数T
可以是方法的输入类型。这意味着我们可以使用Comparable
接口的一个子类作为方法参数的类型,例如:fun sort(list: List<Comparable<in String>>) {// 排序逻辑... }
在这个例子中,
sort
函数接收一个List
,其中的元素类型是Comparable<in String>
,也就是说,我们可以传递Comparable<String>
、Comparable<Any>
等类型的实例。 -
out
:协变(Covariant)
使用out
修饰符声明的类型参数只能用作输出(即返回类型),不能用作输入(即参数类型)。它允许我们使用指定的类型参数的子类作为泛型类型的实参。在函数中,协变类型参数只能作为方法的返回类型。例如,考虑一个协变的接口
Producer
:interface Producer<out T> {fun produce(): T }
这里的
out
修饰符表示类型参数T
可以是方法的输出类型。这意味着我们可以将Producer
接口的一个超类赋值给类型为Producer<out String>
的变量,例如:fun getProducer(): Producer<out String> {// 返回 Producer 的一个子类实例 }
在这个例子中,
getProducer
函数的返回类型是Producer<out String>
,也就是说,我们可以将其返回值赋给类型为Producer<String>
、Producer<Any>
等类型的变量。 -
默认
如果没有指定任何修饰符,则类型参数既可以用作输入(参数类型),也可以用作输出(返回类型)。这种情况下,类型参数是不变的(Invariant)。例如,考虑一个不变的类
Box
:class Box<T>(val item: T) {fun getItem(): T {return item} } // 这里的类型参数 `T` 没有任何修饰符,因此它是不变的。在这种情况下,我们只能使用确切的类型作为泛型类型的实参。 val box: Box<String> = Box("Hello")
通过使用逆变、协变和不变的修饰符,Kotlin 中的泛型提供了更灵活的类型参数关系,以便更好地处理不同的使用场景。
1.3 类型投射
在 Kotlin 中,类型投射(Type Projections)是指在使用泛型类型时对泛型参数的灵活性处理。类型投射允许我们在使用泛型类型时指定类型参数的上界或下界,从而在特定的上下文中对泛型类型进行限制。
Kotlin 中有三种类型投射的方式:
-
上界投射(Upper Bounds Projection):使用
out
关键字
当我们只需要从泛型类型中获取值,而不需要修改该值时,我们可以使用上界投射。使用out
关键字,我们可以指定类型参数的上界。这样,我们可以将泛型类型的实例赋值给类型参数的超类型。例如,考虑一个定义了
Producer
接口的泛型类:interface Producer<out T> {fun produce(): T }
在这个例子中,
out
关键字指定了类型参数T
的上界,表示我们只能从Producer
实例中获取T
类型的值,而不能修改它。 -
下界投射(Lower Bounds Projection):使用
in
关键字
当我们只需要向泛型类型中传递值,而不需要获取值时,我们可以使用下界投射。使用in
关键字,我们可以指定类型参数的下界。这样,我们可以将泛型类型的实例赋值给类型参数的子类型。例如,考虑一个定义了
Consumer
接口的泛型类:interface Consumer<in T> {fun consume(item: T) }
在这个例子中,
in
关键字指定了类型参数T
的下界,表示我们只能向Consumer
实例中传递类型为T
或其子类型的值,而不能传递超类型的值。 -
星投射(Star Projection):使用
*
关键字
当我们既不需要从泛型类型中获取值,也不需要向泛型类型中传递值时,我们可以使用星投射。使用星投射,我们可以在使用泛型类型时忽略类型参数。例如,考虑一个定义了
Box
类的泛型类:class Box<T>(val item: T)
在某些情况下,我们可能不关心具体的类型参数,而只是希望使用一个泛型类型的实例。这时,我们可以使用星投射来表示不关心具体类型参数的情况。
val box: Box<*> = Box("Hello")
在这个例子中,
Box<*>
表示一个未知的类型参数,我们可以使用该实例,但无法获取其中的具体类型。
类型投射允许我们在使用泛型类型时灵活地指定类型参数的上界或下界,从而更好地适应不同的使用场景。
1.4 星号投射
在 Kotlin 中,星号投射(Star Projection)是一种用于处理泛型类型的特殊语法。它通常用于在某些情况下,你可能不需要或无法知道泛型类型的确切参数。星号投射允许你使用未知类型的泛型参数,并且在代码中只能执行一些有限的操作。
星号投射使用星号 (*) 表示未知类型。它可以应用于泛型类、接口和方法。
下面是一个星号投射的示例:
假设有一个简单的泛型类 Box
,定义如下:
class Box<T>(private val item: T) {fun getItem(): T {return item}
}
现在,假设你有一个泛型类 Container
,它包含一个 Box
的列表:
class Container<T>(private val boxes: List<Box<T>>) {fun getFirstItem(): T {return boxes[0].getItem()}
}
假设你有一个 Container
的实例,但是你并不知道 Container
的泛型类型参数 T
是什么。这时,你可以使用星号投射来处理未知类型。
fun processContainer(container: Container<*>) {val item = container.getFirstItem()// 在这里,由于我们不知道 Container 的泛型类型参数 T 是什么,只能执行一些有限的操作,如打印或进行简单处理。println("First item: $item")
}
在上面的示例中,Container<*>
表示一个具有未知泛型类型参数的 Container
实例。我们只能调用返回 T
类型的方法(在这里是 getFirstItem()
),但无法向其中添加新的元素(因为我们不知道它的确切类型)。
需要注意的是,使用星号投射通常是在处理未知泛型类型的情况下使用的,而且通常涉及一些限制,因为编译器无法确切知道类型的信息。因此,在使用星号投射时,必须小心谨慎,确保你只执行合法且安全的操作。
1.5 泛型函数
1.5.1 泛型函数的简介
在 Kotlin 中,你可以创建泛型函数,这些函数允许你在调用时指定参数类型,并且在函数定义中可以使用这些类型参数进行通用的操作。泛型函数能够增加代码的重用性和类型安全性,因为它们可以适用于多种类型而不必为每个类型编写多个函数。
Kotlin 中定义泛型函数使用尖括号 (<>) 来声明泛型类型参数,并将它们放在函数名之前。下面是一个简单的示例:
// 在函数名前声明泛型类型参数 <T>
fun <T> printItem(item: T) {println(item)
}
在这个示例中,我们定义了一个名为 printItem
的泛型函数,它接收一个类型参数为 T
的参数 item
,并简单地打印它。在函数体内,你可以像使用普通类型一样使用类型参数 T
。
现在,你可以在调用 printItem
函数时指定参数的类型,编译器会根据传入的参数类型自动推断出类型参数 T
的具体类型:
printItem("Hello, World!") // 调用时,Kotlin 会推断 T 为 String 类型
printItem(42) // 调用时,Kotlin 会推断 T 为 Int 类型
printItem(true) // 调用时,Kotlin 会推断 T 为 Boolean 类型
除了单个类型参数,你也可以在函数中定义多个泛型类型参数,这使得泛型函数更加灵活:
// 定义一个泛型函数,接收两个类型参数,并返回它们的 Pair
fun <T, U> createPair(first: T, second: U): Pair<T, U> {return Pair(first, second)
}fun main() {val pair1 = createPair(10, "Hello")val pair2 = createPair(true, 3.14)println(pair1) // 输出: (10, Hello)println(pair2) // 输出: (true, 3.14)
}
以上就是 Kotlin 中定义泛型函数的基本语法和用法。泛型函数在处理通用算法或容器类型时特别有用,因为它们能够适用于不同类型的数据,提供更灵活和类型安全的代码。
1.5.2 kotlin泛型函数与java泛型函数对比
Kotlin 和 Java 都支持泛型函数,但它们在语法和使用上有一些不同。下面我们将对 Kotlin 泛型函数和 Java 泛型函数进行对比:
-
语法差异:
Kotlin 泛型函数:
fun <T> genericFunction(item: T): T {// 函数体 }
Java 泛型函数:
public <T> T genericFunction(T item) {// 函数体 }
Kotlin 使用
<T>
放在函数名前来声明泛型类型,而 Java 则使用<T>
放在返回类型之前。 -
类型推断:
Kotlin 泛型函数:
val result = genericFunction("Hello") // 在这里,Kotlin 可以推断出泛型类型 T 为 String
Java 泛型函数:
String result = genericFunction("Hello"); // Java 不能自动推断泛型类型,需要显式指定类型
Kotlin 的类型推断机制通常更加智能,能够自动推断泛型参数类型,而 Java 需要显式指定泛型类型。
-
通配符和星号投射:
Kotlin 泛型函数:
fun processList(list: List<*>) {// 函数体 }
Java 泛型函数:
public void processList(List<?> list) {// 函数体 }
Kotlin 使用星号
*
表示未知类型(星号投射),而 Java 使用?
表示通配符。 -
多重约束:
Kotlin 泛型函数:
fun <T : Number> processNumber(item: T): T {// 函数体 }
Java 泛型函数:
public <T extends Number> T processNumber(T item) {// 函数体 }
Kotlin 使用
:
来指定泛型类型的约束,而 Java 使用extends
关键字。
总体来说,Kotlin 和 Java 的泛型函数在基本概念上是相似的,但具体的语法和使用方式有所不同。如果你熟悉 Java 的泛型,学习 Kotlin 的泛型应该相对容易,因为 Kotlin 是建立在 Java 基础之上并进行了一些改进。
1.6 泛型约束
在 Kotlin 中,你可以对泛型进行约束,以限制泛型类型参数的范围。泛型约束可以帮助你在泛型函数或泛型类中使用特定类型的功能,提高类型安全性并允许更具体的操作。
以下是在 Kotlin 中定义泛型约束的一些方法:
-
上界约束(Upper Bounds):
通过使用
:
来指定泛型类型的上界,你可以限制泛型类型参数只能是指定类或其子类。这意味着类型参数必须是指定类或其子类的实例。// 示例:泛型类型参数 T 必须是 Number 类或其子类的实例 fun <T : Number> printNumberInfo(number: T) {println("Value: ${number.toDouble()}") }
-
多重约束(Multiple Bounds):
Kotlin 支持多重约束,即指定一个泛型类型参数必须满足多个约束条件。你可以使用
where
关键字来声明多个约束条件。// 示例:泛型类型参数 T 必须是 Number 类或其子类,并且实现了 Comparable 接口 fun <T> printInfo(item: T) where T : Number, T : Comparable<T> {println("Value: $item") }
-
非空约束(Not-null Constraint):
通过使用
T : Any
来约束泛型类型参数为非空类型。这样,你可以确保泛型参数不接受可空类型。// 示例:泛型类型参数 T 不能为可空类型 fun <T : Any> processItem(item: T) {// 处理非空类型的 item }
-
泛型函数中的类型约束:
在泛型函数中,你也可以对泛型参数进行约束,就像在泛型类中一样。使用
:
和类型名称来指定约束。// 示例:泛型函数中的类型约束 fun <T> processList(list: List<T>) where T : CharSequence, T : Comparable<T> {// 在这里,T 必须是 CharSequence 和 Comparable<T> 的子类型// 可以使用 CharSequence 和 Comparable<T> 接口中定义的功能 }
这些约束可以帮助你在泛型函数或泛型类中获得更具体的类型信息,并确保类型的安全性。在使用约束时,应该选择最合适的约束以满足你的需求,并根据实际情况来决定是否需要单个约束还是多重约束。
1.7 泛型在Android中的使用
在 Android 开发中,Kotlin 的泛型可以在许多地方使用,例如列表适配器、网络请求、异步任务等。这里我将以列表适配器为例来演示 Kotlin 泛型在 Android 中的使用。
假设你有一个简单的数据类 Person
表示人员信息:
data class Person(val name: String, val age: Int)
现在,我们要在 Android 中展示一个 RecyclerView
,显示一组人员信息。我们将使用泛型来创建一个通用的列表适配器,可以在不同的地方重用。
首先,创建一个泛型适配器类 GenericAdapter
:
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerViewclass GenericAdapter<T>(private val items: List<T>,private val itemLayoutResId: Int,private val bindHolder: (item: T, view: View) -> Unit
) : RecyclerView.Adapter<GenericAdapter<T>.ViewHolder>() {override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {val view = LayoutInflater.from(parent.context).inflate(itemLayoutResId, parent, false)return ViewHolder(view)}override fun onBindViewHolder(holder: ViewHolder, position: Int) {val item = items[position]bindHolder(item, holder.itemView)}override fun getItemCount(): Int {return items.size}inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}
在这个适配器类中,我们使用泛型 T
来表示适配器中的数据项类型。items
参数是一个泛型类型的列表,用于存储要展示的数据。itemLayoutResId
参数表示列表项的布局资源 ID,bindHolder
参数是一个函数,用于将数据绑定到列表项的视图上。
现在,我们可以在 MainActivity
中使用这个通用的列表适配器来显示人员信息:
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val peopleList = listOf(Person("John Doe", 30),Person("Jane Smith", 25),Person("Michael Johnson", 40))recyclerView.layoutManager = LinearLayoutManager(this)recyclerView.adapter = GenericAdapter(peopleList, R.layout.item_person) { person, view ->val nameTextView = view.findViewById<TextView>(R.id.nameTextView)val ageTextView = view.findViewById<TextView>(R.id.ageTextView)nameTextView.text = person.nameageTextView.text = person.age.toString()}}
}
在上面的例子中,我们使用 GenericAdapter
来展示人员信息,将每个人员的姓名和年龄显示在列表项中。由于我们使用了泛型,这个通用适配器可以用于显示其他类型的数据,只需更改数据源和布局即可。
这样,我们通过泛型的使用,实现了一个通用的列表适配器,可以在 Android 中更方便地重用。
相关文章:

Kotlin基础(八):泛型
前言 本文主要讲解kotlin泛型,主要包括泛型基础,类型变异,类型投射,星号投射,泛型函数,泛型约束,泛型在Android中的使用。 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 目录 1.1 泛型基…...
Java学习笔记——(10)环境变量path配置及其作用
环境变量的作用为了在 Dos 的任务目录,可以去使用 javac 和 java开发工具命令 先配置 JAVA_HOME 指向 jdk 安装的主目录(避免开发中出现问题) 编辑 path 环境变量(开发环境),增加 %JAVA_HOME%\bin 编辑 path 环境变量(运行环境…...

【图像去噪】基于进化算法——自组织迁移算法(SOMA)的图像去噪研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

TMS WEB Core Crack,TMS软件Delphi组件RADical Web
TMS WEB Core Crack,TMS软件Delphi组件RADical Web 使用我们的现代web应用程序框架,可以节省宝贵的时间并创造丰富的用户体验。我们所有的工具都由经验丰富的开发人员组成的专门团队提供支持。您可以信赖卓越的服务、活跃的社区和我们不断的创新。TMS Software是您的…...

PHP使用Redis实战实录4:单例模式和面向过程操作redis的语法
PHP使用Redis实战实录系列 PHP使用Redis实战实录1:宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案PHP使用Redis实战实录2:Redis扩展方法和PHP连接Redis的多种方案PHP使用Redis实战实录3:数据类型比较、大小限制和性能扩展PHP使用Re…...
解决:移动端H5的<video>初始化拿不到总时长
移动端 在<video>的初始化后,会调用如下事件。 canplay"canplay" 解决方案:<video>添加自动播放属性: autoplay"autoplay" 然后这个方法里,用js在0.01秒后主动关闭播放,接着在0.…...
百度云上传身份证获取身份信息封装
1.目录结构 -script_discerm ------------包 -discerm.py --------------主要逻辑 -__init__.py -id_care---------------文件夹 存放图片 2.安装模块 pip install urllib31.23 pip install requests pip install base64 3.各文件内容 2.1 discerm.py import jsonimpo…...
vscode 上cmake 版本过低
问题: 装了vscode中的camke插件后,报错如下: CMake 3.9 or higher is required. You are running version 3.3.2。 解决办法: 卸载掉插件的cmake。 到官网下载合适的版本,设置系统变量 然后重新下载camke tools&…...

OS-08-事件驱动:C10M是如何实现的?
08-事件驱动:C10M是如何实现的? 你好,我是陶辉。 上一讲介绍了广播与组播这种一对多通讯方式,从这一讲开始,我们回到主流的一对一通讯方式。 早些年我们谈到高并发,总是会提到C10K,这是指服务…...
mysql 主从同步排查和处理 Slave_IO、Slave_SQL
目录 查看主从是否同步 详解Slave_IO、Slave_SQL 判断主从完全同步 各个 Log_File 和 Log_Pos的关系 修复命令 查看主从是否同步 show slave status; Slave_IO_Running、Slave_SQL_Running,这两个值是Yes表示正常,No是异常 使用竖排显示…...

基于解析法和遗传算法相结合的配电网多台分布式电源降损配置(Matlab实现)
目录 1 概述 2 数学模型 2.1 问题表述 2.2 DG的最佳位置和容量(解析法) 2.3 使用 GA 进行最佳功率因数确定和 DG 分配 3 仿真结果与讨论 3.1 33 节点测试配电系统的仿真 3.2 69 节点测试配电系统仿真 4 结论 1 概述 为了使系统网损达到最低值&a…...
07mysql查询语句之子查询
#1.查询和Zlotkey相同部门的员工姓名和工资 SELECT last_name,salary FROM employees WHERE department_id IN ( SELECT department_id FROM employees WHERE last_name Zlotkey ); #2.查询工资比公司平均工资高的员工的员工号࿰…...
笙默考试管理系统-MyExamTest(22)
笙默考试管理系统-MyExamTest(22) 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试管理系统-MyExa…...

Windows 不同方式打开的cmd/dos窗口属性配置不同
文章目录 1. 默认值(控制台窗口)属性2. "C:\Windows\System32\cmd.exe" 属性3. "命令提示符"属性4. 自定义某标题cmd窗口属性5. cmd快捷方式的属性总结 最近在写某个批处理脚本时,意外发现 Windows系统中,在不…...
性能优化-webpack配置gzip
3步搞定,实测1.3Mjs压缩到363k,体积减少70% 1.装包 yarn add compression-webpack-plugin --dev 2.配置webpack 打开config/webpack.config.js 1)在 module.exports 导出函数前面引入插件 // gzip插件 const CompressionPlugin require(&qu…...

RabbitMQ 教程 | 第3章 客户端开发向导
👨🏻💻 热爱摄影的程序员 👨🏻🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻🏫 一位高冷无情的编码爱好者 大家好,我是 DevO…...

基于深度学习的CCPD车牌检测系统(PyTorch+Pyside6+YOLOv5模型)
摘要:基于CCPD数据集的高精度车牌检测系统可用于日常生活中检测与定位车牌目标,利用深度学习算法可实现图片、视频、摄像头等方式的车牌目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集…...
input元素中的form属性有什么用?
在HTML中,input元素的form属性用于指定该输入字段所属的表单(form元素)。通过将input元素的form属性设置为相应的表单的id值,可以将输入字段与表单进行关联。 这个属性对于两个主要目的非常有用: 表单关联࿱…...

【数据结构篇C++实现】- 特殊的线性表 - 串
友情链接:C/C系列系统学习目录 文章目录 串🚀一、串的定义🚀二、串的存储结构🛴(一)串的顺序存储结构1、定长顺序存储表示2、堆分配存储表示 🛴(二)串的链式存储结构3、块…...
DevOps系列文章 之 Springboot单元测试
在没有代码生成工具或尝试一门新的 ORM框架时,当我们希望不去另外写 Service 和 Controller 来验证 DAO 层的代码不希望只通过接口请求的方式来验证时,这时候单元测试的方式就可以帮助我们满足这一需求。 在我们开发Web应用时,经常会直接去观…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

五、jmeter脚本参数化
目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...

Linux系统:进程间通信-匿名与命名管道
本节重点 匿名管道的概念与原理匿名管道的创建命名管道的概念与原理命名管道的创建两者的差异与联系命名管道实现EchoServer 一、管道 管道(Pipe)是一种进程间通信(IPC, Inter-Process Communication)机制,用于在不…...