深入源码P3C-PMD:rule (4)

news2024/11/15 17:31:21

系列文章目录

文章目录

  • 系列文章目录
  • rule 的应用
    • 类别 rule
  • rule 自定义
    • XML rule 定义
    • Tree 漫游
    • 错误报告
    • 生命周期
  • designer

rule相关的代码在每个子 module 的 rule 文件夹。而且也以一些 ruleset 为范围分了文件夹,如下图所示:

在这里插入图片描述
对每个 rule 来说,定义检测规则并抛出错误,报错方法:addViolation

在这里插入图片描述
对应的 rule 相关 message 在 xml 中定义:
 在这里插入图片描述
这里和 spotbugs 是一个思路,message 做 rule 代码与 xml 隔离,配置大于编码。rule 使用引擎调用,并利用 visitor 模式做行为与数据的解耦。整体思路是一脉相承的。


rule 的应用

首先,遍历规则集合rules中的每个规则rule。

  • 检查当前语言版本的规则是否适用于当前的索引。如果不符合,则跳过该规则,不尝试应用它。
  • 创建一个RuleContext对象ctx,用于存储规则应用时的上下文信息。
  • 调用规则的start方法,开始应用规则。
  • 使用TimedOperation对象rcto记录规则应用的时间。
  • 获取规则的目标选择器的访问节点。
  • 遍历目标选择器的访问节点,对每个节点应用规则。
  • 记录应用规则的节点数量。
  • 在应用规则的过程中,捕获并处理可能的运行时异常和栈溢出异常。
  • 在应用规则之后,关闭规则应用的时间记录。
  • 调用规则的end方法,表示规则应用完成。
private void applyOnIndex(TreeIndex idx, Collection<? extends Rule> rules, FileAnalysisListener listener) {
        for (Rule rule : rules) {
            if (!RuleSet.applies(rule, currentLangVer)) {
                continue; // No point in even trying to apply the rule
            }
            
            RuleContext ctx = RuleContext.create(listener, rule);
            rule.start(ctx);
            try (TimedOperation rcto = TimeTracker.startOperation(TimedOperationCategory.RULE, rule.getName())) {

                int nodeCounter = 0;
                Iterator<? extends Node> targets = rule.getTargetSelector().getVisitedNodes(idx);
                while (targets.hasNext()) {
                    Node node = targets.next();

                    try {
                        nodeCounter++;
                        rule.apply(node, ctx);
                    } catch (RuntimeException e) {
                        reportOrRethrow(listener, rule, node, AssertionUtil.contexted(e), true);
                    } catch (StackOverflowError e) {
                        reportOrRethrow(listener, rule, node, AssertionUtil.contexted(e), SystemProps.isErrorRecoveryMode());
                    } catch (AssertionError e) {
                        reportOrRethrow(listener, rule, node, AssertionUtil.contexted(e), SystemProps.isErrorRecoveryMode());
                    }
                }
                
                rcto.close(nodeCounter);
            } finally {
                rule.end(ctx);
            }
        }
    }

类别 rule

和 spotbugs 的能到某些行等的不同,AST 的建立是以元数据为中心,
visit 的类型有如下这些,共 122 个类别:

 public default R visitJavaNode(JavaNode node, P data) { return visitNode(node, data); }
  default R visit(ASTCompilationUnit node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTPackageDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTImportDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModifierList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTClassOrInterfaceDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTExtendsList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTImplementsList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTPermitsList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTEnumDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTEnumBody node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTEnumConstant node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTRecordDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTRecordComponentList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTRecordComponent node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTRecordBody node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTCompactConstructorDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTypeParameters node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTypeParameter node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTClassOrInterfaceBody node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTEmptyDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTFieldDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTVariableDeclarator node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTVariableDeclaratorId node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTReceiverParameter node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayInitializer node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTMethodDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTFormalParameters node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTFormalParameter node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayDimensions node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayTypeDim node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTConstructorDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTBlock node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTExplicitConstructorInvocation node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTInitializer node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTIntersectionType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTClassOrInterfaceType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTypeArguments node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTWildcardType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTPrimitiveType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTVoidType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTThrowsList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAssignmentExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTConditionalExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTInfixExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTypePattern node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTRecordPattern node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTComponentPatternList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTUnaryExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTCastExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTThisExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSuperExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTClassLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTMethodCall node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayAccess node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTFieldAccess node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTMethodReference node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLambdaExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLambdaParameterList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLambdaParameter node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTBooleanLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTNullLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTNumericLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTCharLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTStringLiteral node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArgumentList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTConstructorCall node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAnonymousClassDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayAllocation node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTArrayDimExpr node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTExpressionStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLabeledStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLocalVariableDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTEmptyStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchArrowBranch node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchFallthroughBranch node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchLabel node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSwitchGuard node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTYieldStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTIfStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTWhileStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTDoStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTForeachStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTForStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTForInit node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTStatementExpressionList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTForUpdate node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTBreakStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTContinueStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTReturnStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTThrowStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTSynchronizedStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTryStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTResourceList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTResource node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTCatchClause node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTCatchParameter node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTUnionType node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTFinallyClause node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAssertStatement node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAnnotation node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAnnotationMemberList node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTMemberValuePair node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTMemberValueArrayInitializer node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAnnotationTypeDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAnnotationTypeBody node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTDefaultValue node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleDeclaration node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleRequiresDirective node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleExportsDirective node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleOpensDirective node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleUsesDirective node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleProvidesDirective node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTModuleName node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTAmbiguousName node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTVariableAccess node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTTypeExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTPatternExpression node, P data) { return visitJavaNode(node, data); }
  default R visit(ASTLocalClassStatement node, P data) { return visitJavaNode(node, data); }

rule 自定义

PMD 是基于 AST的检测框架,语法树表示了源代码中的语法与语义特征。 Rule 遍历 AST 并匹配某些条件。
在这里插入图片描述
自定义规则有2种方式: Xpath query 和 Java visitor。 Xpath 直接使用 XML 定义 更简单,但是有一些只能通过 Java 调用 PMD api 的实现,是Xpath无法达到的。

XML rule 定义

新的规则必须在 ruleset 中定义,并使用 class 属性,引用规则的实现。

java rule:
<rule name="MyJavaRule"
      language="java"
      message="Violation!"
      class="com.me.MyJavaRule">
    <description>
        Description
    </description>
    <priority>3</priority>
</rule>
xpath:
<rule name="MyXPathRule"
      language="java"
      message="Violation!"
      class="net.sourceforge.pmd.lang.rule.xpath.XPathRule">
    <description>
        Description
    </description>
    <priority>3</priority>
    <properties>
        <property name="xpath">
            <value><![CDATA[
//ClassOrInterfaceDeclaration
]]></value>
        </property>
    </properties>
</rule>

要写 Java rule,需要完成如下

  1. 编写一个实现接口Rule的Java类。每种语言实现都提供了一个基本规则类来缓解您的痛苦,例如AbstractJavaRule。
  2. 编译此类,将其链接到PMD API(例如,使用PMD作为Maven依赖项)
  3. 将其打包到JAR中,并将其添加到PMD的执行类路径中
  4. 在规则集XML中声明规则

Tree 漫游

开始应用 rule 的时候,会遍历整棵树来寻找错误,每个 rule 都定义了一个特别的 visit 方法。可以根据需要在 visitor 中选择需要的节点 override 该方法。

public class MyRule extends AbstractJavaRule {

    @Override
    public Object visit(ASTVariableId node, Object data) {
        // This method is called on each node of type ASTVariableId
        // in the AST

        if (node.getType() == short.class) {
            // reports a violation at the position of the node
            // the "data" parameter is a context object handed to by your rule
            // the message for the violation is the message defined in the rule declaration XML element
            asCtx(data).addViolation(node);
        }

        // this calls back to the default implementation, which recurses further down the subtree
        return super.visit(node, data);
    }
}

super.visit(node, data) 调用在规则实现中非常常见,因为它通过访问当前节点的所有子代来继续遍历。如果不需要再往子节点遍历,可以不用再调用 super 的方法。

一个加速手段是使用 rulechain。条件是 rule 不需要维护 visit 之间的状态,这类规则也很常见:
在这里插入图片描述
在这里插入图片描述
rulechain 不会递归整棵树,而是只遍历它关心的部分

  • 必须 override buildTargetSelector 方法,工程方法 forType 能用例创建这样的选择器。
  • 继承 AbstractJavaRulechainRule. 调用父类的构造器,并提供所需要的类型
  • visit 方法不能递归,不能调用 super.visit

在这里插入图片描述
在这里插入图片描述
PMD 提供了2中 AST 导航的方式:NodeStream 和 Node api:

ancestors
ancestorsOrSelf
children
descendants
descendantsOrSelf
ancestors
children
descendants

NodeStream.of(someNode)                           // the stream here is empty if the node is null
          .filterIs(ASTVariableDeclaratorId.class)// the stream here is empty if the node was not a variable declarator id
          .followingSiblings()                    // the stream here contains only the siblings, not the original node
          .filterIs(ASTVariableInitializer.class)
          .children(ASTExpression.class)
          .children(ASTPrimaryExpression.class)
          .children(ASTPrimaryPrefix.class)
          .children(ASTLiteral.class)
          .filterMatching(Node::getImage, "0")
          .filterNot(ASTLiteral::isStringLiteral)
          .nonEmpty(); // If the stream is non empty here, then all the pipeline matched

Node api:
getParent
getNumChildren
getChild
getFirstChild
getLastChild
getPreviousSibling
getNextSibling
firstChild

错误报告

addViolation
addViolationWithMessage 这个方法不会使用 xml 中定义的 message。

生命周期

对于每个线程,规则都深拷贝一份,而且每个线程分析的不同的文件集。一个rule 的生命周期,比较简单:

  • start 调用依次,parsing 之前
  • apply 调用 visit 方法
  • end 结束文件处理

designer

若缺少 javafx 框架,下载地址: https://openjfx.cn/dl/
并在环境变量里配置 JAVAFX_HOME
在这里插入图片描述
使用命令调用:

pmd.bat designer

在这里插入图片描述
双击代码行,定位到导航树:
在这里插入图片描述
GUI 相关的比较简单,大家可以自行探索。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1984418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Model Counting 2024 Public Instance Track 1 18000s(5h)测试结果

测试求解器&#xff1a;SharpSAT-TD与SharpSATTD-CH 18000s测试结果 测试结果图 对3600s未得到结果的数据进行18000s的测试&#xff0c;48组数据&#xff0c;最终有4组在18000s&#xff08;5h&#xff09;内解出 测试数据117 SharpSAT-TD输出&#xff1a; SharpSATTD-CH输出…

2024年底前,河南建筑装饰企业资质延期资料准备要点

针对2024年底前河南建筑装饰企业资质延期的资料准备要点&#xff0c;结合当前的政策要求和实际情况&#xff0c;以下是一些关键的准备要点&#xff1a; 一、了解政策与要求 政策关注&#xff1a; 密切关注河南省住房和城乡建设厅及地方建设主管部门发布的最新政策文件、通知公…

万字长文带你入门shell编程(超详细)

一、概述 Shell 是计算机操作系统中用户与操作系统内核之间的接口层&#xff0c;它提供了一种方式让用户能够通过命令行界面&#xff08;CLI&#xff09;与操作系统交互。Shell 可以被视为一个命令解释器&#xff0c;它接收用户输入的命令&#xff0c;解析这些命令&#xff0c…

趋动科技助力中国移动新型智算中心AI算力池化商用实践

由中国通信标准化协会、中国通信学会指导&#xff0c;CCSA TC610 SDN /NFV /AI标准与产业推进委员会主办的2024年云网智联大会于4月10日-11日在北京召开。 趋动科技联合申报的“中国移动新型智算中心AI算力池化商用实践”&#xff0c;获得2023年度SDN、NFV、网络AI优秀案例征集…

欧美农场小游戏 高端链游 休闲的欧美链游农场 【玫瑰庄园】 高端中英-欧美花园链游

#农场小游戏#链游【玫瑰庄园】 高端中英-欧美花园链游 玫瑰花园一、种子&#xff1a;种子分为五种&#xff1a;白玫瑰、红玫瑰、黑玫瑰、紫罗兰、郁金香。种子通过开启盲盒获得。二、种花&#xff1a;玩家开启盲盒获得的种子&#xff0c;会直接种下&#xff0c;种子种下后&…

深入浅出消息队列----【如何保证消息不重复?】

深入浅出消息队列----【如何保证消息不重复&#xff1f;】 消息一定会重复消息幂等消费改造业务符合天然幂等写法数据库唯一索引redis 唯一判断 本文仅是文章笔记&#xff0c;整理了原文章中重要的知识点、记录了个人的看法 文章来源&#xff1a;编程导航-鱼皮【yes哥深入浅出消…

从零开始的大模型训练教程

近年来&#xff0c;随着人工智能技术的迅猛发展&#xff0c;大模型&#xff08;Large Models&#xff09;成为了业界关注的焦点。这些模型&#xff0c;尤其是那些基于Transformer架构的自然语言处理模型&#xff0c;如GPT系列、BERT等&#xff0c;在各种任务上取得了前所未有的…

git add . 警告

这些警告是因为 Git 检测到你的文件使用了不同的换行符&#xff08;LF 或 CRLF&#xff09;&#xff0c;并提示在下次 Git 操作中将会统一换行符为 CRLF。这通常发生在跨平台协作时&#xff0c;例如在 Windows 环境下编辑的文件可能使用 CRLF&#xff0c;而在类 Unix 环境&…

数据结构:基于顺序表实现通讯录系统(含源码)

目录 一、前言 二、各个功能的实现 2.1 初始化通讯录 2.2 添加通讯录数据 2.3 查找通讯录数据 2.4 删除通讯录数据 2.5 修改通讯录数据 2.6 展示通讯录数据​编辑 2.7 销毁通讯录数据 三、添加菜单和测试 四、完整源码 sxb.h sxb.c contact.h contact.c test.c 一、前…

ROS智能移动机器人实训

0.前言 1.任务 1.1.任务实训任务 1.使用/voice_aiui等语音服务完成基本的语音聊天(需唤醒词“元宝”)。 2.语音多点导航 3.语音单点导航 1.2.智能机器人仿真任务 1.3.智能机器人实物操作任务 2.目的 3&#xff0e;使用环境 4.综合项目实验 任务实训 问题 解决办法…

LinuxIO之文件系统的实现

Ext2/3/4 的layout文件系统的一致性&#xff1a; append一个文件的全流程掉电与文件系统的一致性fsck文件系统的日志ext4 mount选项文件系统的debug和dumpCopy On Write 文件系统&#xff1a; btrfs 预备知识&#xff1a;数据库里的transaction(事务)有什么特性&#xff1f; …

前端高薪岗位之大模型端上部署及训练

自2022年ChatGPT发布以来&#xff0c;以大模型为依托的AIGC相关的应用产品&#xff0c;比如ChatGPT、Midjourney、Stable Diffusion等&#xff0c;在社交网站的讨论热度持续攀升&#xff0c;引发了较大范围的好奇与关注。 目前&#xff0c;国内外各个科技大厂在大模型的端侧部…

手机k歌麦克风哪种好,口碑最好的k歌麦克风是哪款,麦克风推荐

​当我们谈论到演讲、表演或者录制视频时&#xff0c;一个高质量的无线麦克风能够使得整个体验提升至一个全新的水平。它不仅能够保证声音的清晰度和真实度&#xff0c;还能够让使用者在演讲或者表演时更加自信和舒适。基于对市场的深入研究和用户体验的考量&#xff0c;我挑选…

Langchain-Chatchat+Xinference集成部署

Langchain-ChatchatXinference集成部署 安装环境&#xff1a; 系统&#xff1a;Anolis OS 8.9 python版本&#xff1a;Python 3.9.19 Langchain-Chatchat版本&#xff1a;0.3.1.3 Xinference版本&#xff1a;v0.13.3 模型选择&#xff08;下载时需要科学上网&#xff09;&#…

一些常见的中间件漏洞

Tomcat 之CVE-2017-12615 靶场搭建使用vulhub-master/tomcat/CVE-2017-12615 第一步、访问网站 第二步、首页抓包改为put方式提交 网上找一个jsp的一句话木马 使用webshell工具链接即可 Tomcat 之tomcat8 vulhub-master/tomcat/tomcat8 继续访问页面 这次我们点击登录&…

ES6中的Promise、async、await,超详细讲解!

Promise是es6引入的异步编程新解决方案&#xff0c;Promise实例和原型上有reject、resolve、all、then、catch、finally等多个方法&#xff0c;语法上promise就是一个构造函数&#xff0c;用来封装异步操作并可以获取其成功或失败的结果&#xff0c;本篇文章主要介绍了ES6中的P…

spring原理(第十天)

jdk 和 cglib 在 Spring 中的统一 Spring 中对切点、通知、切面的抽象如下 切点&#xff1a;接口 Pointcut&#xff0c;典型实现 AspectJExpressionPointcut 通知&#xff1a;典型接口为 MethodInterceptor 代表环绕通知 切面&#xff1a;Advisor&#xff0c;包含一个 Advic…

政务服务技能竞赛规则流程方案

此次政务服务技能竞赛以“强服务、优素质、促提升、共发展”为目标&#xff0c;通过以赛代练、以赛促建、比学赶超、全面提升&#xff0c;激发各级政务服务工作人员学政策、钻业务、练技能的热情和积极性&#xff0c;全面推动行政效能提升与营商环境建设&#xff0c;铸造新时代…

pytorch和deep learning技巧和bug解决方法短篇收集

有一些几句话就可以说明白的观点或者解决的的问题&#xff0c;小虎单独收集到这里。 torch.hub.load how does it work 下载预训练模型再载入&#xff0c;用程序下载链接可能失效。 model torch.hub.load(ultralytics/yolov5, yolov5s)model torch.hub.load(ultralytics/y…

IROS2024 | DarkGS:学习神经照明和3D高斯重新照明,用于黑暗中机器人探索

DarkGS&#xff1a;学习神经照明和3D高斯重新照明&#xff0c;用于黑暗中机器人探索 论文标题&#xff1a;DarkGS: Learning Neural Illumination and 3D Gaussians Relighting for Robotic Exploration in the Dark 论文地址&#xff1a;https://arxiv.org/abs/2403.10814 研…