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

Dubbo之PojoUtils源码分析

功能概述

  • PojoUtils是一个工具类,能够进行深度遍历,将简单类型与复杂类型的对象进行转换,在泛化调用时用到(在泛化调用中,主要将Pojo对象与Map对象进行相互转换)

功能分析

核心类PojoUtils分析

主要成员变量分析

private static final ConcurrentMap<String, Method> NAME_METHODS_CACHE = new ConcurrentHashMap<String, Method>(); //方法名与Method的缓存(为了减少反射获取Method调用),key的值用类名和参数类型拼接,如:"org.apache.dubbo.common.model.Person.setName(java.lang.String)"
private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<Class<?>, ConcurrentMap<String, Field>>(); //字段所在类Class、字段名、字段信息Filed的缓存

主要成员方法分析

generalize将复杂对象转换为简单对象

private static Object generalize(Object pojo, Map<Object, Object> history) { //pojo对象的成员属性(会递归转换,pojo=》Map,直到所有属性为dubbo定义的基本类型)if (pojo == null) {return null;}if (pojo instanceof Enum<?>) {return ((Enum<?>) pojo).name(); //枚举类型,输出枚举的名称}if (pojo.getClass().isArray() && Enum.class.isAssignableFrom(pojo.getClass().getComponentType())) { //处理Enum数组int len = Array.getLength(pojo);String[] values = new String[len];for (int i = 0; i < len; i++) { //枚举数组会转换为String数组,数组元素的值为枚举名values[i] = ((Enum<?>) Array.get(pojo, i)).name();}return values;}if (ReflectUtils.isPrimitives(pojo.getClass())) { //基本类型直接返回,不做处理return pojo;}if (pojo instanceof Class) { //Class类的实例,返回类名称return ((Class) pojo).getName();}Object o = history.get(pojo);if (o != null) {return o;}history.put(pojo, pojo);if (pojo.getClass().isArray()) { //pojo对象为数组类型int len = Array.getLength(pojo);Object[] dest = new Object[len];history.put(pojo, dest);for (int i = 0; i < len; i++) {Object obj = Array.get(pojo, i);dest[i] = generalize(obj, history);}return dest;}if (pojo instanceof Collection<?>) { //pojo对象为集合类型Collection<Object> src = (Collection<Object>) pojo;int len = src.size();Collection<Object> dest = (pojo instanceof List<?>) ? new ArrayList<Object>(len) : new HashSet<Object>(len); //区分出List或Set类型,并创建对应的集合实例history.put(pojo, dest);for (Object obj : src) { //遍历集合元素,依次将元素进行转换dest.add(generalize(obj, history));}return dest;}if (pojo instanceof Map<?, ?>) { //pojo对象为Map类型Map<Object, Object> src = (Map<Object, Object>) pojo;Map<Object, Object> dest = createMap(src); //根据原Map类型,创建对应的Map对象history.put(pojo, dest);for (Map.Entry<Object, Object> obj : src.entrySet()) {dest.put(generalize(obj.getKey(), history), generalize(obj.getValue(), history)); //key、value都可能是pojo对象,所以都需要进行转换}return dest;}Map<String, Object> map = new HashMap<String, Object>();history.put(pojo, map);if (GENERIC_WITH_CLZ) {map.put("class", pojo.getClass().getName()); //设置pojo对象的Class类}for (Method method : pojo.getClass().getMethods()) {if (ReflectUtils.isBeanPropertyReadMethod(method)) { //判断是否读取bean的方法(即get/is方法)try {/*** 处理步骤:* 1)从方法名中获取到属性名* 2)调用pojo对应的方法获取值,并通过generalize转换(传入history是做临时缓存,若能从history取到则用之)* 3)将属性名和值设置到map中*/map.put(ReflectUtils.getPropertyNameFromBeanReadMethod(method), generalize(method.invoke(pojo), history));} catch (Exception e) {throw new RuntimeException(e.getMessage(), e);}}}// public fieldfor (Field field : pojo.getClass().getFields()) {if (ReflectUtils.isPublicInstanceField(field)) { //判断是否是公共的实例字段try {Object fieldValue = field.get(pojo);if (history.containsKey(pojo)) {Object pojoGeneralizedValue = history.get(pojo); //已经转换过的字段,就不再转换if (pojoGeneralizedValue instanceof Map&& ((Map) pojoGeneralizedValue).containsKey(field.getName())) {continue;}}if (fieldValue != null) {map.put(field.getName(), generalize(fieldValue, history));}} catch (Exception e) {throw new RuntimeException(e.getMessage(), e);}}}return map;
}
  • 代码分析:generalize方法的作用是把复杂类型对象转换为简单类型的对象,如将Pojo对象转换为Map对象,Pojo对象的成员对象若还是复杂类型,会递归调用进行转换。

realize将简单对象转换为复杂对象

private static Object realize0(Object pojo, Class<?> type, Type genericType, final Map<Object, Object> history) { //将简单类型转换为复杂类型(如:将Map对象转换为指定类型的pojo对象,将Map的属性值,通过set方法设置到pojo对象中,type为目标类型)if (pojo == null) {return null;}if (type != null && type.isEnum() && pojo.getClass() == String.class) { //将String转换为枚举类型return Enum.valueOf((Class<Enum>) type, (String) pojo);}if (ReflectUtils.isPrimitives(pojo.getClass())&& !(type != null && type.isArray()&& type.getComponentType().isEnum()&& pojo.getClass() == String[].class)) { //将String数组转换为枚举数组return CompatibleTypeUtils.compatibleTypeConvert(pojo, type);}Object o = history.get(pojo); //history:当方法在递归调用时,会用到(用缓存使用)if (o != null) {return o;}history.put(pojo, pojo);if (pojo.getClass().isArray()) { //处理数组类型的pojoif (Collection.class.isAssignableFrom(type)) { //目标类型是集合类型Class<?> ctype = pojo.getClass().getComponentType(); //获取数组元素的类型int len = Array.getLength(pojo); //获取数组对应长度Collection dest = createCollection(type, len);history.put(pojo, dest);for (int i = 0; i < len; i++) {Object obj = Array.get(pojo, i); //返回数组中指定下标的值Object value = realize0(obj, ctype, null, history); //依次将对象转换为目标类型,如Map转换为pojo类型dest.add(value);}return dest;} else {Class<?> ctype = (type != null && type.isArray() ? type.getComponentType() : pojo.getClass().getComponentType());int len = Array.getLength(pojo);Object dest = Array.newInstance(ctype, len);history.put(pojo, dest);for (int i = 0; i < len; i++) {Object obj = Array.get(pojo, i);Object value = realize0(obj, ctype, null, history);Array.set(dest, i, value);}return dest;}}if (pojo instanceof Collection<?>) { //处理集合类型的pojoif (type.isArray()) { //集合转换为数组Class<?> ctype = type.getComponentType();Collection<Object> src = (Collection<Object>) pojo;int len = src.size();Object dest = Array.newInstance(ctype, len); //创建指定类型和长度的数组history.put(pojo, dest);int i = 0;for (Object obj : src) {Object value = realize0(obj, ctype, null, history); //将数组中的元素依次转换为指定类型pojo对象Array.set(dest, i, value);i++;}return dest;} else {Collection<Object> src = (Collection<Object>) pojo;int len = src.size();Collection<Object> dest = createCollection(type, len);history.put(pojo, dest);for (Object obj : src) { //遍历集合元素,依次转化到目标类型的pojo对象Type keyType = getGenericClassByIndex(genericType, 0);Class<?> keyClazz = obj == null ? null : obj.getClass();if (keyType instanceof Class) {keyClazz = (Class<?>) keyType;}Object value = realize0(obj, keyClazz, keyType, history);dest.add(value);}return dest;}}if (pojo instanceof Map<?, ?> && type != null) { //处理Map类型的pojo(JSONObject:JSON对象,实现了Map接口,也属于Map的实例对象,所以会进入此处)Object className = ((Map<Object, Object>) pojo).get("class"); //获取Map中的"class"键对应的值,是在generalize方法中设置的(单个的pojo中设置的)if (className instanceof String) {try {type = ClassUtils.forName((String) className); //解析的目标类的Class类} catch (ClassNotFoundException e) {// ignore}}// special logic for enumif (type.isEnum()) { //目标类型为枚举Object name = ((Map<Object, Object>) pojo).get("name"); //取出枚举名称if (name != null) {return Enum.valueOf((Class<Enum>) type, name.toString()); //使用枚举名,构建枚举对象}}Map<Object, Object> map;// when return type is not the subclass of return type from the signature and not an interfaceif (!type.isInterface() && !type.isAssignableFrom(pojo.getClass())) { //type非接口且pojo不是type的子类型try {map = (Map<Object, Object>) type.newInstance();Map<Object, Object> mapPojo = (Map<Object, Object>) pojo;map.putAll(mapPojo);if (GENERIC_WITH_CLZ) {map.remove("class");}} catch (Exception e) {//ignore errormap = (Map<Object, Object>) pojo; //type类型不为Map时,使用原始的pojo转换}} else {map = (Map<Object, Object>) pojo; //直接强转为Map类型}if (Map.class.isAssignableFrom(type) || type == Object.class) { //解析的目标类为Map时final Map<Object, Object> result;// fix issue#5939Type mapKeyType = getKeyTypeForMap(map.getClass()); //获取key的泛型参数对应的实际类型Type typeKeyType = getGenericClassByIndex(genericType, 0); //获取目标类型的泛型参数的第一个实际参数boolean typeMismatch = mapKeyType instanceof Class //Type为Class实例时,表明是基本类型或原始类型,如String、int等&& typeKeyType instanceof Class&& !typeKeyType.getTypeName().equals(mapKeyType.getTypeName()); //判断key、value类型为基本类型或原始类型,且类型相同if (typeMismatch) { //输入对象的key与目标Map的key类型不匹配是,创建新的Mapresult = createMap(new HashMap(0));} else {result = createMap(map); //类型匹配时,直接使用目标Map(会转换为具体的Map类型,如:转换为LinkedHashMap类型)}history.put(pojo, result);for (Map.Entry<Object, Object> entry : map.entrySet()) {Type keyType = getGenericClassByIndex(genericType, 0); //获取泛型参数列表指定位置的实际类型Type valueType = getGenericClassByIndex(genericType, 1);Class<?> keyClazz; //获取key参数类型对应的Classif (keyType instanceof Class) { //基本类型或原始类型(如:int、Boolean、String等)keyClazz = (Class<?>) keyType;} else if (keyType instanceof ParameterizedType) { //参数化类型(如:List<ArrayList<String>> 是泛型参数,取实际类型后为ArrayList<String>,实际参数属于参数类型)keyClazz = (Class<?>) ((ParameterizedType) keyType).getRawType();} else { //keyType为Null时,取条目中key的类型(其它类型,如类型变量类型T、通配符类型?等)keyClazz = entry.getKey() == null ? null : entry.getKey().getClass();}Class<?> valueClazz; //获取value参数类型对应的Classif (valueType instanceof Class) {valueClazz = (Class<?>) valueType;} else if (valueType instanceof ParameterizedType) {valueClazz = (Class<?>) ((ParameterizedType) valueType).getRawType();} else {valueClazz = entry.getValue() == null ? null : entry.getValue().getClass();}Object key = keyClazz == null ? entry.getKey() : realize0(entry.getKey(), keyClazz, keyType, history); //递归调用,将key转换为目标类型的对象Object value = valueClazz == null ? entry.getValue() : realize0(entry.getValue(), valueClazz, valueType, history); //递归调用,将value转换为目标类型的对象result.put(key, value);}return result;} else if (type.isInterface()) { //解析的目标类为接口时,产生接口对应的代理类Object dest = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] {type}, new PojoInvocationHandler(map)); //使用jdk代理机制为接口创代理对象,并指定处理器PojoInvocationHandler,在接口方法被调用时,就会触发处理器中方法执行指定逻辑history.put(pojo, dest);return dest;} else {Object dest = newInstance(type); //构造解析的目标类的实例history.put(pojo, dest); //设置到缓存Map中for (Map.Entry<Object, Object> entry : map.entrySet()) { //遍历Map中的条目,找到对应目标对象的属性,使用反射机制调用Method,依次设置值Object key = entry.getKey();if (key instanceof String) { //只处理key为String的条目String name = (String) key;Object value = entry.getValue();if (value != null) {Method method = getSetterMethod(dest.getClass(), name, value.getClass()); //通过属性获取set方法(从缓存中获取,若没有则通过反射获取Method,再设置到缓存中)Field field = getField(dest.getClass(), name); //获取属性对应的字段Filed信息if (method != null) {if (!method.isAccessible()) {method.setAccessible(true);}Type ptype = method.getGenericParameterTypes()[0]; //获取set方法的第一个参数类型value = realize0(value, method.getParameterTypes()[0], ptype, history); //将值转换为指定类型的对象try {method.invoke(dest, value); //使用反射机制,设置目标对象的属性值} catch (Exception e) {String exceptionDescription = "Failed to set pojo " + dest.getClass().getSimpleName() + " property " + name+ " value " + value + "(" + value.getClass() + "), cause: " + e.getMessage();logger.error(exceptionDescription, e);throw new RuntimeException(exceptionDescription, e);}} else if (field != null) {value = realize0(value, field.getType(), field.getGenericType(), history);try {field.set(dest, value);} catch (IllegalAccessException e) {throw new RuntimeException("Failed to set field " + name + " of pojo " + dest.getClass().getName() + " : " + e.getMessage(), e);}}}}}if (dest instanceof Throwable) { //目标对象为异常对象时,设置异常信息Object message = map.get("message");if (message instanceof String) {try {Field field = Throwable.class.getDeclaredField("detailMessage");if (!field.isAccessible()) {field.setAccessible(true);}field.set(dest, message);} catch (Exception e) {}}}return dest;}}return pojo;}

关联类PojoInvocationHandler分析

类中核心代码分析

private static class PojoInvocationHandler implements InvocationHandler { //Pojo代理处理器private Map<Object, Object> map; //在创建代理对象时指定的public PojoInvocationHandler(Map<Object, Object> map) {this.map = map;}@Override@SuppressWarnings("unchecked")public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //为接口生成代理对象,在调用接口方法时,会回调该方法if (method.getDeclaringClass() == Object.class) {return method.invoke(map, args);}String methodName = method.getName();Object value = null;if (methodName.length() > 3 && methodName.startsWith("get")) {value = map.get(methodName.substring(3, 4).toLowerCase() + methodName.substring(4)); //截取方法名,获取属性名,从map中获取相应的值} else if (methodName.length() > 2 && methodName.startsWith("is")) {value = map.get(methodName.substring(2, 3).toLowerCase() + methodName.substring(3));} else {value = map.get(methodName.substring(0, 1).toLowerCase() + methodName.substring(1));}if (value instanceof Map<?, ?> && !Map.class.isAssignableFrom(method.getReturnType())) { //返回类型非Map时,调用realize0进行转换value = realize0((Map<String, Object>) value, method.getReturnType(), null, new IdentityHashMap<Object, Object>());}return value;}
}
  • 代码分析:在转换的目标类型为接口时type.isInterface(),使用jdk动态代理创建接口的代理对象,PojoInvocationHandler为代理对象的调用处理器,包含了提取属性的逻辑

问题点答疑

  • 在realize、generalize方法中都包含了参数Map<Object, Object> history,用途是什么?
    • 解答:在Pojo属性为复杂类型时,即需要递归转换或解析时,就可以把已经处理过的结果放入Map中,传递给下一个转换或解析。下次处理前,会判断是否已经处理过,处理过的就不再处理。这样已经处理过的类型就不用处理了,提升处理性能。

归纳总结

  • PojoUtils转换中,简单类型包含:基本类型、Number、Date、元素为基本类型的数组、集合类型等。
  • 在类型转换时,会进行递归调用,一直解析到位简单类型为止。

相关文章:

Dubbo之PojoUtils源码分析

功能概述 PojoUtils是一个工具类&#xff0c;能够进行深度遍历&#xff0c;将简单类型与复杂类型的对象进行转换&#xff0c;在泛化调用时用到&#xff08;在泛化调用中&#xff0c;主要将Pojo对象与Map对象进行相互转换&#xff09; 功能分析 核心类PojoUtils分析 主要成员…...

【C++】—— C++11新特性之 “右值引用和移动语义”

前言&#xff1a; 本期&#xff0c;我们将要的介绍有关 C右值引用 的相关知识。对于本期知识内容&#xff0c;大家是必须要能够掌握的&#xff0c;在面试中是属于重点考察对象。 目录 &#xff08;一&#xff09;左值引用和右值引用 1、什么是左值&#xff1f;什么是左值引用…...

谈一谈redis脑裂

什么是redis脑裂 &#xff08;1&#xff09;一主多从架构中&#xff0c;主节点与客户端通信正常&#xff0c;主节点与哨兵、从节点连接异常&#xff0c;客户端仍正常写入数据 &#xff08;2&#xff09;哨兵判定主节点下线&#xff0c;重新选主 &#xff08;3&#xff09;原主…...

基于原生Servlet使用模板引擎Thymeleaf访问界面

我们常在Spring Boot项目中使用Thymeleaf模板引擎,今天突发奇想&#xff0c;尝试原生Servlet访问&#xff01; 说做就做 搭建完整的WEB项目 其中的大部分依赖都是后续报错 追加进来的 导入依赖 thymeleaf-3.0.11.RELEASE.jar 第一次访问 访问地址: http://localhost:8080…...

【C语言】15-函数-1

1. 初步认识函数 通过前几章的学习,已经可以编写一些简单的 C 语言程序了,但是如果程序的功能比较多,规模比较大,把所有的程序代码都写在一个主函数(main函数)中,就会使主函数变得庞杂、头绪不清,使阅读和维护程序变得困难。此外,有时程序中要多次实现某一功能就需要…...

08-信息收集-架构、搭建、WAF等

信息收集-架构、搭建、WAF等 信息收集-架构、搭建、WAF等一、前言说明二、CMS识别技术三、源码获取技术四、架构信息获取技术五、站点搭建分析1、搭建习惯-目录型站点2、搭建习惯-端口类站点3、搭建习惯-子域名站点4、搭建习惯-类似域名站点5、搭建习惯-旁注&#xff0c;c段站点…...

Qt --- 显示相关设置 窗口属性等

主界面&#xff0c;窗口 最小化 最大化 关闭按钮、显示状态自定义&#xff1a; setWindowFlags(Qt::CustomizeWindowHint); setWindowFlags(Qt::WindowCloseButtonHint); //只要关闭按钮 setWindowFlags(Qt::WindowFlags type) Qt::FrameWindowHint:没有边框的窗口 Qt::Window…...

使用小程序实现左侧菜单,右侧列表双向联动效果

目录 引言理解双向联动效果的重要性scrollview属性介绍实现左侧菜单数据准备渲染菜单列表监听菜单点击事件实现右侧列表数据结构设计初始数据渲染监听列表滚动事件左侧菜单与右侧列表联动获取当前滚动位置计算对应菜单项联动效果优化用户体验考虑平滑滚动效果菜单高亮状态...

selenium中处理验证码问题

验证码 基本作用&#xff1a;可以实现当前访问页面的数据安全性、还可以减少用户的并发数&#xff1b; 类型&#xff1a;1、纯数字、纯字母&#xff1b;2、汉字组合&#xff1b;3、数学运算题&#xff1b;4、滑动&#xff1b;5、图片&#xff08;选不同的、选相同、成语顺序&…...

EMR电子病历系统 SaaS电子病历编辑器源码 电子病历模板编辑器

EMR&#xff08;Electronic Medical Record&#xff09;指的是电子病历。它是一种基于电子文档的个人医疗记录&#xff0c;可以包括病人的病史、诊断、治疗方案、药物处方、检查报告和护理计划等信息。EMR采用计算机化的方式来存储、管理和共享这些信息&#xff0c;以便医生和医…...

一些自定义hooks

文章目录 1、点击框外隐藏弹窗hook 1、点击框外隐藏弹窗hook **描述&#xff1a;**有一个需要自己封装弹窗的组件&#xff0c;实现点击弹窗框外时隐藏弹窗 代码&#xff1a; import { useEffect } from “react”; // 点击框外hooks import { useEffect } from "react&q…...

基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法

文献计量学是指用数学和统计学的方法&#xff0c;定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体&#xff0c;注重量化的综合性知识体系。特别是&#xff0c;信息可视化技术手段和方法的运用&#xff0c;可直观的展示主题的研究发展历程、研究现状、研究…...

lEC 61068-2-14_2023环境试验.第2-14部分:试验.试验N:温度变化, 最新版发布

https://download.csdn.net/download/m0_67373485/88251313 lEC 61068-2-14_2023环境试验.第2-14部分:试验.试验N:温度变化 A change of temperature test is intended to determine the effect on the specimen of a changeof temperature or a succession of changes of tem…...

CFDEM学习笔记

本文用来记录自己学习CFDEM的笔记。 资料总结 虚拟机&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1MPMTJQfl76mW0H5bbT_rAg 提取码&#xff1a;rqli 开机密码&#xff1a;530944988 知乎博客&#xff1a;作者说明了如何关闭颗粒碰撞计算来达到提升计算速度。 Githu…...

SpringBoot入门篇1 - 简介和工程创建

目录 SpringBoot是由Pivotal团队提供的全新框架&#xff0c; 其设计目的是用来简化Spring应用的初始搭建以及开发过程。 1.创建入门工程案例 ①创建新模块&#xff0c;选择Spring初始化&#xff0c;并配置模块相关基础信息 ②开发控制器类 controller/BookController.jav…...

MyBatis-Plus updateById不更新null值

文章目录 前言方式一 调整全局的验证策略方式二 调整字段验证注解方式三 使用 UpdateWrapper 前言 在 MyBatis-Plus 中&#xff0c;使用updateById&#xff0c;null字段并不会更新&#xff0c;其实是和更新的策略有关&#xff0c;当然&#xff0c;也有插入策略&#xff0c;本文…...

用pytorch实现AlexNet

AlexNet经典网络由Alex Krizhevsky、Hinton等人在2012年提出&#xff0c;发表在NIPS&#xff0c;论文名为《ImageNet Classification with Deep Convolutional Neural Networks》&#xff0c;论文见&#xff1a;http://www.cs.toronto.edu/~hinton/absps/imagenet.pdf &#xf…...

LeetCode560.和为k的子数组

这道题我用的是暴力法&#xff0c;当然也是不断的提交不断发现问题改出来的&#xff0c;比如我之前是算到和大于目标值就break&#xff0c;其实不行因为后面还可以有负数&#xff0c;我把break删了。后面和为目标之后就答案1然后break然后下一次遍历&#xff0c;测试用例中就出…...

echarts 的dataZoom滑块两端文字被遮挡

问题&#xff1a; 期望&#xff1a; 解决方案&#xff1a; 1&#xff1a;调整宽度&#xff08;4版本的没有width属性&#xff09; 2. 参考&#xff1a;echarts图标设置dataZoom拖拽时间轴时自动调整两侧文字的位置_datazoom 位置_乌栖曲的博客-CSDN博客 设置文字的定位 cons…...

MongoDB基本使用

在 MongoDB 中我们可以使用use命令来创建数据库&#xff0c;如果该数据库不存在&#xff0c;则会创建一个新的数据库&#xff0c;如果该数据库已经存在&#xff0c;则将切换到该数据库。使用use命令创建数据库的语法格式如下&#xff1a; --use database_name use my_db1;数据…...

C++ 中的左值(Lvalues)和右值(Rvalues)

C 中有两种类型的表达式&#xff1a; 左值&#xff08;lvalue&#xff09;&#xff1a;左值参数是可被引用的数据对象&#xff0c;例如&#xff0c;变量、数组元素、结构成员、引用和解除引用的指针都是左值。非左值包括字面常量&#xff08;用引号起的字符串除外&#xff0c;…...

html流光按钮

出处bilibili猫咪爱狗 <!DOCTYPE html> <html><head><style>body {/*内容居中&#xff0c;背景色*/height: 100vh;display: flex;justify-content: center; align-items: center;background-color: #000;}a { /*水平垂直居中*/position: re…...

HAProxy+nginx搭建负载均衡群集

目录 一、常见的Web集群调度器 二、HAProxy群集介绍 1、Haproxy的特性 : 2、Haproxy常用的调度算法 ① 轮询调度&#xff08;Round Robin&#xff09; ② 最小连接数&#xff08;Least Connections&#xff09; ③ 基于来源访问调度算法&#xff08;Source Hashing&am…...

logback-spring.xml 的配置及详解(直接复制粘贴可用)

logback-spring.xml 的配置及详解 一、注意实现二、配置及详解 一、注意实现 logback-spring.xml 中有三处需要根据实际业务进行修改&#xff0c;直接查找“&#xff08;根据业务修改&#xff09;”即可进行定位。 如果不想修改&#xff0c;直接复制粘贴到自己系统运行也可以&…...

C语言易错点整理

前言&#xff1a; 本文涵盖了博主在平常写C语言题目时经常犯的一些错误&#xff0c;在这里帮大家整理出来&#xff0c;一些易错点会帮大家标识出来&#xff0c;希望大家看完这篇文章后有所得&#xff0c;引以为戒~ 一、 题目&#xff1a; 解答&#xff1a; 首先在这个程序中…...

60.每日一练:回文数(力扣)

目录 问题描述 代码解决以及思想 解法&#xff08;一&#xff09; 知识点 解法&#xff08;二&#xff09; 问题描述 代码解决以及思想 解法&#xff08;一&#xff09; class Solution { public:bool isPalindrome(int x) {string arr to_string(x); // 将整数转换为…...

算法通关村第5关【青铜】| Hash和队列的特征

1.Hash基础 &#xff08;1&#xff09;基础 哈希也称为散列&#xff0c;通过算法变成固定长度的输出值&#xff0c;存入对应的位置 例如这个算法为取模算法&#xff0c;indexnumber 模 7 存入1到15 &#xff08;2&#xff09;碰撞处理 当多个元素映射到同一位置上时就产生…...

C++:函数

函数参数的传递机制 C的每个程序至少有一个函数&#xff0c;即主函数main()&#xff0c;函数也是类的方法的实现手段。C的函数包括两类&#xff1a;预定于函数和用户自定义函数。 函数的定义格式为&#xff1a; <返回值类型><函数名>(<参数列表>) <函…...

Linux网络编程:libevent事件通知库

文章目录&#xff1a; 一&#xff1a;libevent库 二&#xff1a;libevent框架 1.常规事件event 1.1 创建事件event&#xff08;event_new&#xff09; 1.2 添加事件到 event_base&#xff08;event_add&#xff09; 1.3 从event_base上摘下事件&#xff08;event_del&a…...

java.lang.reflect.InvocationTargetException:null报未知异常

在项目上线过程中&#xff0c;突然出现大量异常信息&#xff0c;堆栈信息如下&#xff1a; java.lang.reflect.InvocationTargetException: null at jdk .internal.reflect.GeneratedMethodAccessor792 .invoke(Unknown Source) ~[?:?] at jdk.internal.reflect.DelegatingM…...

多网站怎么做seo/新平台推广赚钱

转载于&#xff1a;https://www.ibm.com/developerworks/cn/linux/l-pipebid/ 问题和常见方法Linux 提供了 popen 和 pclose 函数 (1)&#xff0c;用于创建和关闭管道与另外一个进程进行通信。其接口如下&#xff1a;FILE *popen(const char *command&#xff0c; const char *…...

承建网站/西安高端网站建设公司

公司升级了gitlab&#xff0c;统一管理了代码库&#xff0c;要求项目组将gitlab仓库迁移到新的地址。 当然也可以在新地址里面创建项目&#xff0c;然后将代码上传上去&#xff0c;不过这种方法比较繁琐&#xff0c;分支、标签什么的也带不过去。所以按照gitlab导入的提示&…...

做网站要用框架吗/海外短视频软件

123序号#问题#参考答案#题型1#输出1~100中所有整数的平方和。 #338350#基本2#求1~210之间所有整数的立方和并输出结果。 #490844025#基本3#求1~55的平方根的和。(保留小数点两位) #275.43#基本4#求S11/21/3……1/100。 #5.187388#基本5#计算y12/33/54/7…n/(2*n-1)的值, n50, 要…...

h5微信网站建设/搜索引擎网址有哪些

假如p是质数&#xff0c;且gcd(a,p)1&#xff0c;那么 a^(p-1)≡1&#xff08;mod p&#xff09; 也就是a^(p-1) %p1 据说它是欧拉定理的一种特殊情况&#xff0c;也就是 比较神奇&#xff0c;据说很出名很出名很出名 先回顾一下乘法逆元 x的最小整数解称为a模m的逆元 如果这个…...

帮人做海报的网站/谷歌广告平台

「无零整数」是十进制表示中 不含任何 0 的正整数。 给你一个整数 n&#xff0c;请你返回一个 由两个整数组成的列表 [A, B]&#xff0c;满足&#xff1a; A 和 B 都是无零整数 A B n 题目数据保证至少有一个有效的解决方案。 如果存在多个有效解决方案&#xff0c;你可…...

网页展示模板/重庆seo优化公司

题目描述 给定整数m以及n各数字A1,A2,…An&#xff0c;将数列A中所有元素两两异或&#xff0c;共能得到n(n-1)/2个结果&#xff0c;请求出这些结果中大于m的有多少个。 输入描述: 第一行包含两个整数n,m. 第二行给出n个整数A1&#xff0c;A2&#xff0c;…&#xff0c;An。 对于…...