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

idea plugin插件开发——入门级教程(IntelliJ IDEA Plugin)

手打不易,如果转摘,请注明出处!

注明原文:idea plugin插件开发——入门级教程(IntelliJ IDEA Plugin)-CSDN博客


目录

前言

官方

官方文档

代码示例

开发前必读

Intellij、Gradle、JDK 版本关系

plugin.xml 配置介绍

开发第一个插件

初始化项目工程

创建ToolWindow

注册ToolWindow

运行和调试

打包和发布

修改开源插件Restful-Toolkit

新增导出工具类

创建一个导出按钮

TreePanelWindow添加按钮

常用API

获取plugin.xml里面配置的类

获取选择的文件夹和项目

获取鼠标所在的元素

获取方法的参数

踩坑问题

问题:Cannot start compilation: the output path is not specified for module "zj-idea-plugin-gradle-run-test".

相关文章推荐


前言

有时候想开发一款自己的idea插件,但是无从下手,这篇文章就是教你如何入门!

    官方

    官方文档

    IntelliJ Platform SDK | IntelliJ Platform Plugin SDK

    代码示例

    https://github.com/JetBrains/intellij-sdk-code-samples

    开发前必读

    Intellij、Gradle、JDK 版本关系

    环境搭建第一步先确认好自己的Intellij IDEA和Gradle之间的版本关系,找到对应的版本才能保证不出现冲突报错。

    通过gradle开发idea插件,环境版本适配_idea 指定gradle版本-CSDN博客

    plugin.xml 配置介绍

    <idea-plugin><!-- 插件的id,id全局唯一 --><id>com.example.zhang</id><!-- 插件的名称和版本, 会在idea插件界面显示 --><name>example</name><version>1.0</version><!-- 作者信息 --><vendor email="zhang@qq.com" url="http://www.zhang.com">www.zhang.com</vendor><!-- 插件描述,要大于40个字符--><description>This is my ABCDEFGHIJKLMNOPQRSTUVWXYZ plugins, it is convenient for us to...</description><!-- 插件版本更新记录 --><change-notes><![CDATA[<ul><li><b>Version 1.0.1</b> Convert to ABCDEFGHIJKLMNOPQRSTUVWXYZ plugin</li><li><b>Version 1.0.0</b> Release 2020 and earlier.</li></ul>]]></change-notes><!-- 兼容的idea版本 --><idea-version since-build="191.0"/><!-- 依赖模块 --><depends>com.intellij.modules.platform</depends><!-- 插件扩展 --><extensions defaultExtensionNs="com.intellij"><!-- 例如 toolWindow、executor 都可以在这里定义 --><!-- 插件定义的自定义操作,例如菜单项、工具栏按钮等。每个操作都有一个唯一的 id,一个实现类 class,以及可选的快捷键定义 --></extensions><!-- 插件具备哪些动作按钮 --><actions><!-- 例如 各种action 都可以在这里定义 --><!-- 插件定义的自定义操作,例如菜单项、工具栏按钮等。每个操作都有一个唯一的 id,一个实现类 class,以及可选的快捷键定义 --></actions><!-- 定义一些初始化 Component,高版本已弃用 --><project-components><!-- Component --></project-components>
    </idea-plugin>

    开发第一个插件

    初始化项目工程

    前提是需要把JDK、Gradle、IDEA都安装好,网上有多教程,这里不再赘述。

    打开IntelliJ IDEA,新建一个IDE Plugin工程。

    整体目录结构大致如下,冗余的配置可以删掉

    先修改 gradle-wrapper.properties 中的gradle版本,例如:

    idea、jdk、gradle用什么版本,之前已经提到了,参考:

    通过gradle开发idea插件,环境版本适配_idea 指定gradle版本-CSDN博客

    distributionBase=GRADLE_USER_HOMEdistributionPath=wrapper/distsdistributionUrl=https\://services.gradle.org/distributions/gradle-x.x.x-bin.zipzipStoreBase=GRADLE_USER_HOMEzipStorePath=wrapper/dists

    修改 build.gradle 文件(如果不存在就新建)

    一般 gradle 中的 repositories 是必须修改的,否则网络不通。

    dependencies 依赖包和 intellij 的version根据自己的实际情况选择。

    buildscript {repositories {maven {// 内网maven库地址,下载依赖的第三方库url 'http://xxxxxxxxxx/artifactory/maven-public/'}maven {// 内网JetBrains仓库,下载依赖的IDE和jdk等,用于编译和运行插件url 'http://xxxxxxxxxx/artifactory/jetbrains-public/'}}dependencies {// gradle-intellij-plugin用于构建JetBrains插件, 请确保始终升级到最新版本classpath "org.jetbrains.intellij.plugins:gradle-intellij-plugin:0.6.5"}
    }plugins {id 'java'id 'org.jetbrains.intellij' version '0.4.10'id "org.jetbrains.kotlin.jvm" version "1.3.41"
    }group 'org.example'
    version '1.0-SNAPSHOT'repositories {maven {url 'http://xxxxxxxxxxxxxxxxx/artifactory/maven-public/'}
    }dependencies {implementation 'com.alibaba:druid:1.2.8'
    }// See https://github.com/JetBrains/gradle-intellij-plugin/
    intellij {version '2019.3.5'// 必须,否则无法找到 PsiClass 等plugins = ['java', 'gradle']intellij.updateSinceUntilBuild false
    }sourceCompatibility = 1.8
    targetCompatibility = 1.8apply {"java""terminal""ant"
    }test {useJUnitPlatform()
    }tasks.withType(JavaCompile) {options.encoding = "UTF-8"
    }buildPlugin {buildSearchableOptions.enabled = false
    }

    修改plugin.xml 的配置内容

    注意 idea-version since-build 兼容版本,可以不写,也可以根据你现在开发的版本来指定。

    例如,build.gradle 中,我指定的2019老版本开发的.

    查询官网版本信息:

    Other Versions - IntelliJ IDEA

    内容如下:

    <!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
    <idea-plugin><!-- 插件的id,id全局唯一 --><id>com.example.myFirstIdeaPlugin</id><!-- 插件的名称和版本, 会在idea插件界面显示 --><name>MY_FIRST_IDEA_PLUGIN</name><version>1.0</version><!-- 作者信息 --><vendor email="zhang@qq.com" url="http://www.zhang.com">www.zhang.com</vendor><!-- 插件描述,要大于40个字符--><description>This is my ABCDEFGHIJKLMNOPQRSTUVWXYZ plugins, it is convenient for us to...</description><!-- 插件版本更新记录 --><change-notes><![CDATA[<ul><li><b>Version 1.0.1</b> Convert to ABCDEFGHIJKLMNOPQRSTUVWXYZ plugin</li><li><b>Version 1.0.0</b> Release 2020 and earlier.</li></ul>]]></change-notes><!-- 兼容的idea版本 --><idea-version since-build="193.7288.26"/><!-- 依赖模块 --><depends>com.intellij.modules.platform</depends>
    </idea-plugin>

    对应实际发布后的插件关系如下:

    idea的的gradle setting配置如下:

    配置完成后,建议重新打开IDEA,或者重新初始化一下gradle,如果IDEA未能找到gradle项目,按照下面的方法区添加。

    到这里,我们就完成了项目工程的创建和初始化。

    创建ToolWindow

    我们参考官方教程,来做一个日历插件:

    https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/tool_window/src/main/java/org/intellij/sdk/toolWindow

    这里可能比官方教程稍微详细一点。

    我们先创建好2个目录:

    创建ToolWindow其实就是把面板界面和交互实现,IDEA有个快速创建UI的方法,对目录右键:

    弹框后直接输入名字,并选择绑定class

    idea会创建好form和对应的class,我们只需要在这个上面编辑我们要的组件即可。

    最终我们添加了3个JLabel和2个JButton,注意组件需要填写对应的file name,以便在class类中添加成员属性。

    我们看下自动创建好的类 MyCalendarForm.class

    package com.example.myfirstideaplugin.calendar.ui;import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JPanel;public class MyCalendarForm {private JPanel panel;private JButton refreshButton;private JButton hideButton;private JLabel timeZone;private JLabel time;private JLabel date;
    }

    需要实现一个方法来获取时间,同时对刷新按钮和隐藏按钮添加监听器,图标可以通过 setIcon() 来设置

    最终代码如下:

    
    package com.example.myfirstideaplugin.calendar.ui;import com.intellij.openapi.wm.ToolWindow;import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Calendar;
    import java.util.Objects;import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JPanel;public class MyCalendarForm {private JPanel panel;private JButton refreshButton;private JButton hideButton;private JLabel timeZone;private JLabel time;private JLabel date;public MyCalendarForm(ToolWindow toolWindow) {// 隐藏按钮 监听器hideButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {toolWindow.hide(null);}});// 刷新按钮 监听器refreshButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {timeTime();}});// 初始化调用this.timeTime();}public void timeTime() {// 获取年月日, 并设置 iconCalendar instance = Calendar.getInstance();int day = instance.get(Calendar.DAY_OF_MONTH);int month = instance.get(Calendar.MONTH) + 1;int year = instance.get(Calendar.YEAR);time.setText(day + "/" + month + "/" + year);time.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/icon/calendar/Calendar-icon.png"))));// 获取时分, 并设置 iconint minute = instance.get(Calendar.MINUTE);int hour = instance.get(Calendar.HOUR_OF_DAY);int second = instance.get(Calendar.SECOND);String min = (minute < 10) ? "0" + minute : String.valueOf(minute);String sec = (second < 10) ? "0" + second : String.valueOf(second);date.setText(hour + ":" + min + ":" + sec);date.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/icon/calendar/Time-icon.png"))));// 获取时区long gmtOffset = instance.get(Calendar.ZONE_OFFSET); // offset from GMT in millisecondsString strGmtOffset = String.valueOf(gmtOffset / 3600000);String temp = (gmtOffset > 0) ? "GMT + " + strGmtOffset : "GMT - " + strGmtOffset;timeZone.setText(temp);timeZone.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/icon/calendar/Time-zone-icon.png"))));}public JPanel getContent() {return panel;}}

    到这里,我们把UI和交互写好了,接下来我们要实现 ToolWindowFactory 方法,来定义一个ToolWindow。

    package com.example.myfirstideaplugin.calendar.factory;import com.example.myfirstideaplugin.calendar.ui.MyCalendarForm;
    import com.intellij.openapi.project.Project;
    import com.intellij.openapi.wm.ToolWindow;
    import com.intellij.openapi.wm.ToolWindowFactory;
    import com.intellij.ui.content.Content;
    import com.intellij.ui.content.ContentFactory;import org.jetbrains.annotations.NotNull;public class CalendarToolWindowFactory implements ToolWindowFactory {/*** Create the tool window content.** @param project    current project* @param toolWindow current tool window*/@Overridepublic void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {MyCalendarForm MyCalendarForm = new MyCalendarForm(toolWindow);ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();// createContent()参数一定是 JComponent 的子类Content content = contentFactory.createContent(MyCalendarForm.getContent(), "我的日历", false);toolWindow.getContentManager().addContent(content);}
    }

    至此,一个日历ToolWindow就写好了。接下来只需要注册就可以使用。

    注册ToolWindow

    注册ToolWindow,其实就是去plugin.xml绑定一下ToolWindow,包括id、icon、位置等信息。

    plugin.xml 中添加如下代码

        <!-- 插件扩展 --><extensions defaultExtensionNs="com.intellij"><!-- — — — — — — — — — 示例:日历toolWindow BEGIN— — — — — — — — — --><!-- 参考官方demo:https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/tool_window --><!-- canCloseContents 是否允许用户关闭 --><toolWindow id="我的calendar" icon="/icon/calendar/Calendar-icon.png"anchor="bottom" canCloseContents="true"factoryClass="com.example.myfirstideaplugin.calendar.factory.CalendarToolWindowFactory"></toolWindow></extensions>

    id是该ToolWindow的唯一键,icon是指定图标,anchor表示我们想显示在哪个位置。

    运行和调试

    调试运行的方式如下:

    可以看到,我们的插件生效了.

    每次点击刷新,可以刷新时间

    打包和发布

    打包只需要执行buildPlugin即可

    打包后的目录和包在这里:

    这个zip文件就是我们要的插件安装包,直接安装到IntelliJ IDEA,重启就可以使用了,

    如果想要发布到官方的IntelliJ IDEA插件,直接去官方上传,审核通过后就可以发布全网。

    修改开源插件Restful-Toolkit

    https://github.com/EzioL/plugin-restful-toolkit

    有时候项目很老,没有yaml去定义各个API接口,只有Controller。

    因此我们希望有个插件,能帮助我们一键导出项目所有的API接口。

    新增导出工具类

    package com.ezio.plugin.utils;import com.ezio.plugin.navigator.pojo.ApiInModule;
    import com.ezio.plugin.navigator.pojo.ApiInfo;import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.util.List;public enum FileUtl {;public static String getCurResourcePath(Class<?> cls) {String currPath = "";try {currPath = URLDecoder.decode(cls.getResource("").getPath(), "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}String str = "file:/";currPath = currPath.substring(str.length());return currPath.substring(0, currPath.indexOf("build"));}public static void writeStr(String filePath, List<ApiInModule> apiInModuleList) {File logFile = new File(filePath);// 先判断日志目录是否存在,不存在则先创建if (!logFile.getParentFile().exists()) {boolean mkdirFlag = logFile.getParentFile().mkdirs();if (!mkdirFlag) {throw new RuntimeException("创建文件失败:" + logFile.getParentFile());}}try (BufferedWriter bw = new BufferedWriter(new FileWriter(logFile))) {bw.write("");for (ApiInModule apiInModule : apiInModuleList) {List<ApiInfo> apiInfoList = apiInModule.getApiInfoList();for (ApiInfo apiInfo : apiInfoList) {String fullUrl = apiInfo.getFullUrl();bw.append(fullUrl).append("\n");}}} catch (IOException e) {System.out.println("error:" + e);}}
    }
    

    创建一个导出按钮

    代码如下:

    package com.ezio.plugin.utils;import com.ezio.plugin.navigator.pojo.ApiInModule;
    import com.ezio.plugin.navigator.pojo.ApiInfo;import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.util.List;public enum FileUtl {;public static String getCurResourcePath(Class<?> cls) {String currPath = "";try {currPath = URLDecoder.decode(cls.getResource("").getPath(), "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}String str = "file:/";currPath = currPath.substring(str.length());return currPath.substring(0, currPath.indexOf("build"));}public static void writeStr(String filePath, List<ApiInModule> apiInModuleList) {File logFile = new File(filePath);// 先判断日志目录是否存在,不存在则先创建if (!logFile.getParentFile().exists()) {boolean mkdirFlag = logFile.getParentFile().mkdirs();if (!mkdirFlag) {throw new RuntimeException("创建文件失败:" + logFile.getParentFile());}}try (BufferedWriter bw = new BufferedWriter(new FileWriter(logFile))) {bw.write("");for (ApiInModule apiInModule : apiInModuleList) {List<ApiInfo> apiInfoList = apiInModule.getApiInfoList();for (ApiInfo apiInfo : apiInfoList) {String fullUrl = apiInfo.getFullUrl();bw.append(fullUrl).append("\n");}}} catch (IOException e) {System.out.println("error:" + e);}}
    }
    

      TreePanelWindow添加按钮

      com.ezio.plugin.toolwindow.TreePanelWindow 类下面添加Action,

      actionGroup.add(new ExportToolBar());

      public class TreePanelWindow extends SimpleToolWindowPanel implements DataProvider {private SimpleTree myTree;public TreePanelWindow(SimpleTree tree) {super(true, true);this.myTree = tree;// 设置 tree 线条JBColor color = new JBColor(new Color(11, 6, 39),new Color(36, 38, 39));myTree.setBorder(BorderFactory.createLineBorder(color));// 设置 scrollPane 线条JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree);scrollPane.setBorder(BorderFactory.createLineBorder(JBColor.RED));setContent(scrollPane);final ActionManager actionManager = ActionManager.getInstance();// 设置 toolbar action, 添加一个刷新按钮// createActionToolbar(String place, ActionGroup group, boolean horizontal)DefaultActionGroup actionGroup = new DefaultActionGroup();actionGroup.add(actionManager.getAction("zhang.group.refresh"));actionGroup.add(new ExportToolBar());ActionToolbar actionToolbar = actionManager.createActionToolbar("myPlace", actionGroup, false);setToolbar(actionToolbar.getComponent());myTree.addMouseListener(new TreePanelWindowListener());}
      }

      常用API

      获取plugin.xml里面配置的类

       ServiceManager.getService(XXXX.class);

      获取选择的文件夹和项目

      IdeView ideView = (IdeView)anActionEvent.getRequiredData(LangDataKeys.IDE_VIEW);
      //选择的文件夹
      this.psiDirectory = ideView.getOrChooseDirectory();
      //选择的项目
      this.project = this.psiDirectory.getProject();
      获取选中的类名
      //  e为 AnActionEvent 
      PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
      //获取选中的类名
      String name = psiFile.getVirtualFile().getName();

      获取鼠标所在的元素

      PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);

      获取方法的参数

      PsiParameter[] psiParameters = ((PsiMethodImpl) psiElement).getParameterList().getParameters();

      获取指定文件名的文件

      PsiFile[] psiFiles = FilenameIndex.getFilesByName(project, name, GlobalSearchScope.projectScope(project));

      踩坑问题

      问题:Cannot start compilation: the output path is not specified for module "zj-idea-plugin-gradle-run-test".

      Specify the output path in the Project Structure dialog.

      运行代码的时候报错如下:

      解决:

      如图所示,再Project Structure里面的Modules修改Paths,路径为当前目录\target\classes和\target\test-classes

      相关文章推荐

      idea plugin插件开发1——idea底部窗口(带按钮)_idea下方工具窗口 开发-CSDN博客

      idea plugin插件开发2——预览代码(多窗口)_idea预览代码-CSDN博客

      idea plugin插件开发3——可编辑表单_idea 插件开发filechooserfactory-CSDN博客

      推荐10款高频插件

      1. ​Rainbow Brackets
        功能:为代码中的括号(如圆括号、方括号、花括号)添加彩色高亮,帮助开发者更清晰地识别嵌套结构。
        适用场景:适用于任何需要清晰识别括号嵌套的编程语言,特别适合嵌套较深的代码。
        官网:Rainbow Brackets - IntelliJ IDEs Plugin | Marketplace
         
      2. Generate All Getter And Setter
        功能:快速为POJO类生成所有getter和setter方法,支持带默认值和不带默认值的setter方法。
        适用场景:适用于需要快速生成Java类的getter和setter方法的场景。
        官网:Generate All Getter And Setter - IntelliJ IDEs Plugin | Marketplace
         
      3. Gsonformat
        功能:将JSON字符串格式化为Gson格式的Java类,支持自定义类名和包名。
        适用场景:适用于需要将JSON数据快速转换为Java类的场景。
        官网:Gsonformat - IntelliJ IDEs Plugin | Marketplace
         
      4. MyBatisCodeHelperPro
        功能:为MyBatis框架提供代码生成和辅助功能,包括SQL语句生成、Mapper接口生成等。
        适用场景:适用于使用MyBatis框架的Java项目。
        官网:MyBatisCodeHelperPro - IntelliJ IDEs Plugin | Marketplace
         
      5. Statistic
        功能:提供代码统计功能,包括行数、单词数、字符数等统计信息。
        适用场景:适用于需要快速统计代码量的场景。
        官网:Statistic - IntelliJ IDEs Plugin | Marketplace
         
      6. RESTFul-Tool
        功能:提供RESTful API的测试和调试工具,支持HTTP请求发送、响应查看等。
        适用场景:适用于开发和调试RESTful API。
        官网:RESTFul-Tool - IntelliJ IDEs Plugin | Marketplace
         
      7. Maven Helper
        功能:增强Maven项目的管理功能,支持依赖分析、依赖树查看、依赖冲突解决等。
        适用场景:适用于使用Maven构建的Java项目。
        官网:Maven Helper - IntelliJ IDEs Plugin | Marketplace
         
      8. Java Mybatis SQL Scanner
        功能:扫描MyBatis的SQL语句,检测潜在的错误和问题,支持自定义规则。
        适用场景:适用于使用MyBatis框架的Java项目,特别是需要对SQL语句进行静态分析的场景。
        官网:Java Mybatis SQL Scanner - IntelliJ IDEs Plugin | Marketplace
         
      9. Power Mode II 酷炫风
        功能:为IDEA添加动态效果,如代码输入时的震动、闪光等,增加编程的乐趣。
        适用场景:适用于任何需要增加编程乐趣的场景。
        官网:Power Mode II - IntelliJ IDEs Plugin | Marketplace
         
      10. Arthas Idea
        功能:集成Arthas(一个Java诊断工具)到IntelliJ IDEA中,支持在线调试、监控和诊断Java应用。
        适用场景:适用于需要在线调试和监控Java应用的场景。
        官网:arthas idea - IntelliJ IDEs Plugin | Marketplace
        这些插件可以帮助你更高效地进行Java开发,提升代码质量和开发体验。根据你的具体需求,选择合适的插件进行安装和使用。

      相关文章:

      idea plugin插件开发——入门级教程(IntelliJ IDEA Plugin)

      手打不易&#xff0c;如果转摘&#xff0c;请注明出处&#xff01; 注明原文&#xff1a;idea plugin插件开发——入门级教程&#xff08;IntelliJ IDEA Plugin&#xff09;-CSDN博客 目录 前言 官方 官方文档 代码示例 开发前必读 Intellij、Gradle、JDK 版本关系 plu…...

      61,【1】BUUCTF WEB BUU XSS COURSE 11

      进入靶场 左边是吐槽&#xff0c;右边是登录&#xff0c;先登录试试 admin 123456 admiin# 123456 admin"# 123456 不玩了&#xff0c;先去回顾下xss 回顾完就很尴尬了&#xff0c;我居然用SQL的知识去做xss的题 重来 吐槽这里有一个输入框&#xff0c;容易出现存储型…...

      开发环境搭建-1:配置 WSL (类 centos 的 oracle linux 官方镜像)

      一些 Linux 基本概念 个人理解&#xff0c;并且为了便于理解&#xff0c;可能会存在一些问题&#xff0c;如果有根本上的错误希望大家及时指出 发行版 WSL 的系统是基于特定发行版的特定版本的 Linux 发行版 有固定组织维护的、开箱就能用的 Linux 发行版由固定的团队、社…...

      Spring Boot MyBatis Plus 版本兼容问题(记录)

      Spring Boot & MyBatis Plus 版本兼容问题&#xff08;Invalid value type for attribute factoryBeanObjectType: java.lang.String&#xff09; 问题描述问题排查1. 检查 MapperScan 的路径2. 项目中没有配置 FactoryBean3. 检查 Spring 和 MyBatis Plus 版本兼容性 解决…...

      26. 【.NET 8 实战--孢子记账--从单体到微服务】--需求更新--用户注销、修改用户名、安全设置

      在实际开发过程中&#xff0c;项目需求的变更和增加是常见的情况&#xff0c;因此这篇文章我们就模拟一下项目需求新增的情况。 一、需求 项目经理今天提出了新的功能&#xff0c;需要增加重置密码、安全设置、修改用户名、注销账户这四个功能&#xff0c;这四个功能必须是独…...

      神经网络|(一)加权平均法,感知机和神经元

      【1】引言 从这篇文章开始&#xff0c;将记述对神经网络知识的探索。相关文章都是学习过程中的感悟和理解&#xff0c;如有雷同或者南辕北辙的表述&#xff0c;请大家多多包涵。 【2】加权平均法 在数学课本和数理统计课本中&#xff0c;我们总会遇到求一组数据平均值的做法…...

      OpenHarmony OTA升级参考资料记录

      OpenHarmony 作为一个开源分布式操作系统,通过其强大的 OTA(Over-The-Air)升级能力,为开发者和厂商提供了一套灵活而安全的系统升级方案。 OTA升级方式 根据升级包的应用方式,OpenHarmony 的 OTA 升级可以分为两种:本地升级和网络OTA升级。 本地升级 本地升级是将已制作…...

      在 Kubernetes 上快速安装 KubeSphere v4.1.2

      目录标题 安装文档配置repo安装使用插件 安装文档 在 Kubernetes 上快速安装 KubeSphere 配置repo export https_proxy10.10.x.x:7890 helm repo add stable https://charts.helm.sh/stable helm repo update安装 helm upgrade --install -n kubesphere-system --create-name…...

      【回忆迷宫——处理方法+DFS】

      题目 代码 #include <bits/stdc.h> using namespace std; const int N 250; int g[N][N]; bool vis[N][N]; int dx[4] {0, 0, -1, 1}; int dy[4] {-1, 1, 0, 0}; int nx 999, ny 999, mx, my; int x 101, y 101; //0墙 (1空地 2远方) bool jud(int x, int y) {if…...

      华为OD机试真题---战场索敌

      华为OD机试真题“战场索敌”是一道考察算法和数据结构应用能力的题目。以下是对该题目的详细解析&#xff1a; 一、题目描述 有一个大小是NM的战场地图&#xff0c;被墙壁’#‘分隔成大小不同的区域。上下左右四个方向相邻的空地’.‘属于同一个区域&#xff0c;只有空地上可…...

      计算机网络 (53)互联网使用的安全协议

      一、SSL/TLS协议 概述&#xff1a; SSL&#xff08;Secure Sockets Layer&#xff09;安全套接层和TLS&#xff08;Transport Layer Security&#xff09;传输层安全协议是工作在OSI模型应用层的安全协议。SSL由Netscape于1994年开发&#xff0c;广泛应用于基于万维网的各种网络…...

      c++算法贪心系列

      本篇文章&#xff0c;同大家一起学习贪心算法&#xff01;&#xff01;&#xff01; 第一题 题目链接 2208. 将数组和减半的最少操作次数 - 力扣&#xff08;LeetCode&#xff09; 题目解析 本题重点&#xff1a;最终的数组和要小于原数组和的一半&#xff0c;且求这一操作的…...

      【Maui】注销用户,采用“手势”点击label弹窗选择

      文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 方法一&#xff1a;前端绑定3.2 方法二&#xff1a;后端绑定3.3 注销用户的方法 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创…...

      智慧脚下生根,智能井盖监测终端引领城市安全新革命

      在繁忙的都市生活中&#xff0c;我们往往只关注地面的繁华与喧嚣&#xff0c;却忽略了隐藏在地面之下的基础设施——井盖。这些看似不起眼的井盖&#xff0c;实则承担着排水、通讯、电力等重要功能&#xff0c;是城市安全运转的重要一环。然而&#xff0c;传统的井盖管理面临着…...

      Word2Vec如何优化从中间层到输出层的计算?

      文章目录 Word2Vec如何优化从中间层到输出层的计算&#xff1f;用负采样优化中间层到输出层的计算负采样方法的关键思想负采样的例子负采样的采样方法 Word2Vec如何优化从中间层到输出层的计算&#xff1f; 重要性&#xff1a;★★ 用负采样优化中间层到输出层的计算 以词汇…...

      第七篇:vue3 计算属性:computed

      v-model "firstName". // v-model. 就是双向绑定的意思 <br/> // 通过 v-model 进行绑定姓&#xff1a;<input type"text" v-model "firstName"><br/>名&#xff1a;<input type"text" v-model"lastN…...

      搭建k8s集群

      一、准备工作&#xff08;所有节点&#xff09; 在开始部署之前&#xff0c;我们需要对所有节点进行以下准备工作。 1.1、关闭防火墙 # 关闭防火墙 systemctl stop firewalld# 禁止防火墙开机自启 systemctl disable firewalld1.2、 关闭 SELinux # 永久关闭 SELinux sed -…...

      Android SystemUI——最近任务应用列表(十七)

      对于最近任务应用列表来说,在 Android 原生 SystemUI 中是一个单独的组件。 <string-array name="config_systemUIServiceComponents" translatable="false">……<item>com.android.systemui.recents.Recents</item> </string-arra…...

      java 根据前端传回的png图片数组,后端加水印加密码生成pdf,返回给前端

      前端传回的png图片数组&#xff0c;后端加水印加密码生成pdf&#xff0c;返回给前端 场景&#xff1a;重点&#xff1a;maven依赖controllerservice 场景&#xff1a; 当前需求&#xff0c;前端通过html2canvas将页面报表生成图片下载&#xff0c;可以仍然不满意。 需要java后…...

      《探秘鸿蒙Next:如何保障AI模型轻量化后多设备协同功能一致》

      在鸿蒙Next的多设备协同场景中&#xff0c;确保人工智能模型轻量化后功能的一致性是一项极具挑战性但又至关重要的任务。以下是一些关键的方法和策略。 统一的模型架构与标准 采用标准化框架&#xff1a;选择如TensorFlow Lite、PyTorch Mobile等在鸿蒙Next上适配良好的轻量化…...

      YSYX学习记录(八)

      C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

      linux arm系统烧录

      1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

      技术栈RabbitMq的介绍和使用

      目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

      JVM虚拟机:内存结构、垃圾回收、性能优化

      1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

      并发编程 - go版

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

      关于uniapp展示PDF的解决方案

      在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

      【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

      Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

      【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

      FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

      C++11 constexpr和字面类型:从入门到精通

      文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

      RLHF vs RLVR:对齐学习中的两种强化方式详解

      在语言模型对齐&#xff08;alignment&#xff09;中&#xff0c;强化学习&#xff08;RL&#xff09;是一种重要的策略。而其中两种典型形式——RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09; 与 RLVR&#xff08;Reinforcement Learning with Ver…...