Spring boot 2.0 升级到 3.3.1 的相关问题 (六)
文章目录
- Spring boot 2.0 升级到 3.3.1 的相关问题 (六)
- `spring-data-redis` 和 `Spring AOP` 警告的问题
- 问题描述
- 问题调研
- 结论
- 解决方案
- 方案1-将冲突的Bean 提升为`InfrastructureBean`
- 方案2
- 其他相关资料
Spring boot 2.0 升级到 3.3.1 的相关问题 (六)
spring-data-redis
和 Spring AOP
警告的问题
问题描述
启动的时候会出现类似于这种内容的警告信息
2024-07-22T17:48:33.448+08:00 WARN 40892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alibaba.druid.spring.boot3.autoconfigure.stat.DruidSpringAopConfiguration' of type [com.alibaba.druid.spring.boot3.autoconfigure.stat.DruidSpringAopConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-22T17:48:33.560+08:00 WARN 40892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource.druid-com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties' of type [com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-22T17:48:33.565+08:00 WARN 40892 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'advisor' of type [org.springframework.aop.support.RegexpMethodPointcutAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
问题调研
在2.0 版本中,也有类似的日志,但是info
级别的。
[2024-07-24 13:33:00.107] [] [main] INFO : [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:328] - Bean 'com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure' of type [com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure$$EnhancerBySpringCGLIB$$2505a1af] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2024-07-24 13:33:00.166] [] [main] INFO : [c.a.d.s.b.a.DruidDataSourceAutoConfigure:56] - Init DruidDataSource
[2024-07-24 13:33:01.989] [] [main] INFO : [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:328] - Bean 'org.springframework.boot.context.properties.ConversionServiceDeducer$Factory' of type [org.springframework.boot.context.properties.ConversionServiceDeducer$Factory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2024-07-24 13:33:12.885] [] [main] INFO : [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:328] - Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
相关代码
org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker#postProcessAfterInitialization
2.0 版本
@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {if (logger.isInfoEnabled()) {logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +"] is not eligible for getting processed by all BeanPostProcessors " +"(for example: not eligible for auto-proxying)");}}return bean;}
3.0 版本代码
org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker#postProcessAfterInitialization
@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {if (logger.isWarnEnabled()) {Set<String> bppsInCreation = new LinkedHashSet<>(2);for (String bppName : this.postProcessorNames) {if (this.beanFactory.isCurrentlyInCreation(bppName)) {bppsInCreation.add(bppName);}}if (bppsInCreation.size() == 1) {String bppName = bppsInCreation.iterator().next();if (this.beanFactory.containsBeanDefinition(bppName) &&beanName.equals(this.beanFactory.getBeanDefinition(bppName).getFactoryBeanName())) {logger.warn("Bean '" + beanName + "' of type [" + bean.getClass().getName() +"] is not eligible for getting processed by all BeanPostProcessors " +"(for example: not eligible for auto-proxying). The currently created " +"BeanPostProcessor " + bppsInCreation + " is declared through a non-static " +"factory method on that class; consider declaring it as static instead.");return bean;}}logger.warn("Bean '" + beanName + "' of type [" + bean.getClass().getName() +"] is not eligible for getting processed by all BeanPostProcessors " +"(for example: not eligible for auto-proxying). Is this bean getting eagerly " +"injected into a currently created BeanPostProcessor " + bppsInCreation + "? " +"Check the corresponding BeanPostProcessor declaration and its dependencies.");}}return bean;}private boolean isInfrastructureBean(@Nullable String beanName) {if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);return (bd.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);}return false;}}
问题是由引入的spring-data-commons
包引起的。
结论
核心是因为org.springframework.aop.config.internalAutoProxyCreator
Bean (通常对应的实现类是AnnotationAwareAspectJAutoProxyCreator
) 会对所有的Bean进行增强,在这个过程中会出现要增强的Bean是BeanPostProcessor
比如org.springframework.data.web.config.ProjectingArgumentResolverRegistrar.ProjectingArgumentResolverBeanPostProcessor
,但他本身又在这个AnnotationAwareAspectJAutoProxyCreator
之后构建,导致在构建依赖的Bean 检测BeanPostProcessor
时,发现存在还没有完全完成构建的BeanPostProcessor
。
如果是自定义的BeanPostProcessor
,只要实现了Ordered
或者PriorityOrdered
接口就可以搞定,这个是因为
在Spring处理BeanPostProcessor
初始化时,会根据是否实现了PriorityOrdered
或者Ordered
接口来按照不同分组进行构建,其中org.springframework.aop.config.internalAutoProxyCreator
Bean 就是归类在Ordered
组。核心代码如下:
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
方法(3.0版本)
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// WARNING: Although it may appear that the body of this method can be easily// refactored to avoid the use of multiple loops and multiple lists, the use// of multiple lists and multiple passes over the names of processors is// intentional. We must ensure that we honor the contracts for PriorityOrdered// and Ordered processors. Specifically, we must NOT cause processors to be// instantiated (via getBean() invocations) or registered in the ApplicationContext// in the wrong order.//// Before submitting a pull request (PR) to change this method, please review the// list of all declined PRs involving changes to PostProcessorRegistrationDelegate// to ensure that your proposal does not result in a breaking change:// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22// 获取待处理构建的BeanPostProcessor的名称列表String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.//计算BeanPostProcessor的最终目标数量int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;//增加一个BeanPostProcessorChecker的检测器,就是这个检查器输出警告日志beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, postProcessorNames, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.// 按照PriorityOrdered、Ordered 和noneOrdered 3种情况分组,顺序完成初始化和注册。List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//完成PriorityOrdered 的 BeanPostProcessor 的初始化BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.// 按照Ordered排序顺序,进行排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//追加到beanFactory的BeanPostProcessors (前面的BeanPostProcessorChecker检查的就是这个)registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String ppName : orderedPostProcessorNames) {//完成Ordered 的 BeanPostProcessor 的初始化BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);//追加到beanFactory的BeanPostProcessors ,如果自定义的BeanPostProcessors 在这里还没完成初始化,而是要到后面才能开始初始化,这种情况就会出现BeanPostProcessorChecker的警告。registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {//完成NonOrdered 的 BeanPostProcessor 的初始化BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);//追加到beanFactory的BeanPostProcessors,完成所有的BeanPostProcessors构建和配置registerBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
解决方案
方案1-将冲突的Bean 提升为InfrastructureBean
参考BeanPostProcessorChecker
的检测代码
if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount)
让触发警告的Bean
的!isInfrastructureBean(beanName)
不满足即可。
可以使用 @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Bean("txInterceptor")@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionInterceptor transactionInterceptor(){return new TransactionInterceptor(tx , transactionAttributeSource()) ;}
也可以使用实现BeanFactoryPostProcessor
接口的postProcessBeanFactory
方法来动态修改BeanDefinition
的Role
@Configuration
public class ConfigBeanPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {static final Set<String> beanNames = Set.of(
// "projectingArgumentResolverBeanPostProcessor""com.alibaba.druid.spring.boot3.autoconfigure.stat.DruidSpringAopConfiguration","spring.datasource.druid-com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties","advisor");@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {for(String defaultBeanName:beanNames){if (beanFactory.containsBeanDefinition(defaultBeanName)) {BeanDefinition beanDefinition = beanFactory.getBeanDefinition(defaultBeanName);//修改bean的角色为spring框架级别的beanbeanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);}}}/*** Get the order value of this object.* <p>Higher values are interpreted as lower priority. As a consequence,* the object with the lowest value has the highest priority (somewhat* analogous to Servlet {@code load-on-startup} values).* <p>Same order values will result in arbitrary sort positions for the* affected objects.** @return the order value* @see #HIGHEST_PRECEDENCE* @see #LOWEST_PRECEDENCE*/@Override public int getOrder() {return HIGHEST_PRECEDENCE;}
}
当然也可以二者结合使用。需要注意的是记得把相关的依赖Bean都要标记上,否则一旦有一个没标记上就仍会出现警告。
自定义的
BeanPostProcessor
最好还要实现Ordered
或者PriorityOrdered
接口,否则这个自定义的BeanPostProcessor
也会触发这个警告。
方案2
暂时没找到具体可行方案,思路大概就这几个方向
1、让AnnotationAwareAspectJAutoProxyCreator
不增强指定的BeanPostProcessor
2、提前完成指定BeanPostProcessor
的构建
3、将没有实现Ordered
或者PriorityOrdered
接口的BeanPostProcessor
通过特殊手段追加上。
(通过调试验证是可行,但代码实现目前没找到突破口)
其他相关资料
相关demo: spring-boot-upgrade-from2to3-demo
这个Demo可以直接直接展示这个警告日志的输出。
相关资料:
https://github.com/spring-projects/spring-boot/issues/38558
相关文章:
Spring boot 2.0 升级到 3.3.1 的相关问题 (六)
文章目录 Spring boot 2.0 升级到 3.3.1 的相关问题 (六)spring-data-redis 和 Spring AOP 警告的问题问题描述问题调研结论解决方案方案1-将冲突的Bean 提升为InfrastructureBean方案2 其他相关资料 Spring boot 2.0 升级到 3.3.1 的相关问题 ÿ…...

C++模版基础知识与STL基本介绍
目录 一. 泛型编程 二. 函数模板 1. 概念 2. 函数模版格式 3. 函数模版的原理 4. 模版函数的实例化 (1). 隐式实例化 (2.) 显式实例化 5. 模版参数的匹配原则 三. 类模板 1. 类模板的定义格式 2. 类模板的实例化 四. STL的介绍 1. 什么是STL? 2. STL的版…...

Android 防止重复点击
1.第一种方式: // 两次点击按钮之间的点击间隔不能少于1000毫秒 private static final int MIN_CLICK_DELAY_TIME 700; private static long lastClickTime; /** * 是否是快速点击 * return */ public static boolean isFastClick() { …...

使用阿里云云主机通过nginx搭建文件服务器
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、准备基础环境二、安装配置nginx三、阿里云安全组配置安全组配置 
微信Android一面凉经(2024)
微信Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《微信Android一面凉经(2024)》。 面试职位: 微信-客户端开发工程师-基础功能(广州) And…...

VMware、Docker - 让虚拟机走主机代理,解决镜像封禁问题
文章目录 虚拟机全局代理配置找到 VMnet8 的 IPv4 地址代理相关配置虚拟机代理配置 Docker 代理配置修改镜像修改 Docker 代理配置 虚拟机全局代理配置 找到 VMnet8 的 IPv4 地址 a)打开此电脑,输入 “控制面板”,然后回车. b)之…...
版本管理|为什么不推荐使用Git Rebase
文章目录 什么是 Git Rebase?如何使用 Git Rebase?基本语法示例更多选项 注意事项何时使用何时避免其他注意事项 为什么需要谨慎使用 Git Rebase?面试中的常见问题问题 1: Git Rebase 和 Git Merge 有何不同?问题 2: 为什么有时应…...
Https post 请求时绕过证书验证方案
解决异常:Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address xxx.xx.xx.xx found // Https POST 请求private cn.hutool.json.JSON PostGsData(String url, String appKey, String token, Map<String, Ob…...

C# 数组常用遍历方式
// 假设数组Point[] points new Point[2];// 第一种遍历 forfor (int i 0; i < points.Length; i){Point p points[i];Console.WriteLine($"X{p.X},y{p.Y}");}// 第二种遍历 foreachforeach (Point p in points){Console.WriteLine($"X{p.X},y{p.Y}"…...

【JavaScript】详解Day.js:轻量级日期处理库的全面指南
文章目录 一、Day.js简介1. 什么是Day.js?2. 安装Day.js 二、Day.js的基本用法1. 创建日期对象2. 格式化日期3. 解析日期字符串4. 操作日期5. 比较日期 三、Day.js的高级功能1. 插件机制2. 国际化支持 四、实际应用案例1. 事件倒计时2. 日历应用 在JavaScript开发中…...

AI算法与图像处理 | 吴恩达团队新作!多模态方向
本文来源公众号“AI算法与图像处理”,仅用于学术分享,侵权删,干货满满。 原文链接:吴恩达团队新作!多模态方向 研究评估了先进多模态基础模型在 10 个数据集上的多样本上下文学习,揭示了持续的性能提升。…...

云服务器Ubuntu18.04进行Nginx配置
云服务器镜像版本信息:Ubuntu 18.04 server 64bit,本文记录了在改版本镜像上安装Nginx,并介绍了Nginx配置文件目录,便于后面再次有需求时进行复习。 文章目录 Nginx的安装Nginx配置文件分析 Nginx的安装 1.执行下面命令进行安装…...

SQL labs-SQL注入(四,sqlmap对于post传参方式的注入)
本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 序言:本文主要讲解基于SQL labs靶场,sqlmap工具进行的post传参方式的SQL注入。 传参方式有两类,一类是直接在url栏内进行url编码后进行的传参&am…...

R包:plot1cell单细胞可视化包
介绍 plot1cell是用于单细胞数据seurat数据对象的可视化包。 安装 ## You might need to install the dependencies below if they are not available in your R library. bioc.packages <- c("biomaRt","GenomeInfoDb","EnsDb.Hsapiens.v86&qu…...

Tent混沌人工蜂群与粒子群混合算法遇到问题,具体问题及解决方案如文。
🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 问题描述 Tent混沌人工蜂…...

Python文献调研(一)环境搭建
一、安装Python版本 1.点击进入Python官网 Download Python | Python.org 2.根据自己的需求选择python的版本,点击【Download】 3.自定义安装路径,记得勾选Add Python xxx to PATH 这步是自动配置环境变量的,如果忘记勾选,建议…...
URL重写
目录 步骤1 规则语法 Nginx URL重写规则语法 Apache URL重写规则语法 步骤2 规则配置 Apache URL重写规则配置 启用mod_rewrite模块 配置.htaccess文件 编写重写规则 测试重写规则 Nginx URL重写规则配置 配置server或location块 测试重写规则 步骤1 规则语法 Ngin…...

git配置环境变量
一.找到git安装目录 打开此git安装目录下的bin文件,复制此文件路径 二.配置环境变量 2.1 右键点击此电脑的属性栏 2.2 点击高级系统配置 2.3 点击环境变量 2.4 按图中步骤进行配置 三.配置完成 win r 输入cmd打开终端 终端页面中输入 git --version 如图所示…...

vue3编程-import.meta.glob实现动态路由(菜单)
import.meta.glob 是vite提供的批量懒加载组件的方法 本地开发环境: const modules import.meta.glob(../views/**/*.vue)这段代码返回的modules是一个Map: key是vue文件的相对路径,值是一个函数,将函数打印出来,如…...

富唯智能转运机器人:高效、智能、未来的选择
在现代工业中,高效的物流和物料处理是提升生产效率的关键。富唯智能转运机器人,以其卓越的技术和智能化的设计,为各行业提供了完美的解决方案。 产品概述 富唯智能转运机器人搭载ICD系列核心控制器,拥有多种移载平台,…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...