-
Idea拉取Jar包,报Unable to import maven project: See logs for details 查看日志信息No implementation for org.apache.maven.model.path.PathTranslator was bound 解决办法: IDEA执行Maven报错 Unable to import maven project: See logs for details Help -> Show Log in Explorer 查看详细的错误日志 1) No implementation for org.apache.maven.model.path.PathTranslator was bound. while locating org.apache.maven.model.path.PathTranslator for field at org.apache.maven.model.interpolation.AbstractStringBasedModelInterpolator.pathTranslator(Unknown Source) at org.codehaus.plexus.DefaultPlexusContainer$1.configure(DefaultPlexusContainer.java:350) 2) No implementation for org.apache.maven.model.path.UrlNormalizer was bound. while locating org.apache.maven.model.path.UrlNormalizer for field at org.apache.maven.model.interpolation.AbstractStringBasedModelInterpolator.urlNormalizer(Unknown Source) at org.codehaus.plexus.DefaultPlexusContainer$1.configure(DefaultPlexusContainer.java:350) 解决办法 Maven与IDEA版本不一致导致: 当前:Maven-3.6.3 IDEA2019.01 修改Maven版本为:3.5.4 https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/ 最后:修改maven在IDEA中的版本配置即可解决。 ———————————————— 原文链接:https://blog.csdn.net/qq_31016939/article/details/137032201
-
VM options这项需要我们自己填写,我填的是VM options : -Xms256m -Xmx256m -XX:PermSize=32M -XX:MaxPermSize=128m 每一项以空格隔开 参数说明 -Xms256m:设置JVM初始堆内存为256m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 -Xmx256m:设置JVM最大堆内存为256m。 -Xss128k:设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K。应当根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。需要注意的是:当这个值被设置的较大(例如>2MB)时将会在很大程度上降低系统的性能。 -Xmn2g:设置年轻代大小为2G。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。 -XX:NewSize=1024m:设置年轻代初始值为1024M。 -XX:MaxNewSize=1024m:设置年轻代最大值为1024M。 -XX:PermSize=256m:设置持久代初始值为256M。 -XX:MaxPermSize=256m:设置持久代最大值为256M。 -XX:NewRatio=4:设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:4。 -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为2:4,即1个Survivor区占整个年轻代大小的1/6。 -XX:MaxTenuringThreshold=7:表示一个对象如果在Survivor区(救助空间)移动了7次还没有被垃圾回收就进入年老代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。 标准参数,所有JVM都必须支持这些参数的功能,而且向后兼容;例如: -client——设置JVM使用Client模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或开发调试;在32位环境下直接运行Java程序默认启用该模式。 -server——设置JVM使Server模式,特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境。在具有64位能力的JDK环境下默认启用该模式。 非标准参数(-X),默认JVM实现这些参数的功能,但是并不保证所有JVM实现都满足,且不保证向后兼容; 非稳定参数(-XX),此类参数各个JVM实现会有所不同,将来可能会不被支持,需要慎重使用; ———————————————— 原文链接:https://blog.csdn.net/style_L_/article/details/129079538
-
流程如下: 打开 IntelliJ IDEA: 启动你的 IntelliJ IDEA。 打开新的项目或窗口: 可以打开一个新的项目,或者在当前项目中打开一个新的窗口。 配置新的运行/调试配置: 在 IntelliJ IDEA 的工具栏中,找到并点击右侧的编辑配置按钮(位于运行/调试配置的旁边,通常是一个小下拉箭头)。 选择 Edit Configurations: 在弹出的菜单中,选择 "Edit Configurations"。 添加新的配置: 在打开的配置窗口左上角,点击加号按钮或复制按钮,以添加一个新的配置。 选择 Application 配置类型: 在弹出的菜单中,选择 "Application" 配置类型。 配置新的运行/调试配置: 在右侧的配置窗口中,配置以下参数: Name(名称): 为你的配置起一个名称,以便区分。 Main class(主类): 指定你的 Java 主类。 VM options(虚拟机选项): 在这里输入你想要配置的虚拟机选项,比如 -Duser.language=en。 Program arguments(程序参数): 如果你的程序需要参数,可以在这里添加。 保存配置: 确保点击窗口底部的 "OK" 按钮来保存你的配置。 运行新的配置: 在 IntelliJ IDEA 的工具栏中选择你刚刚配置的运行/调试配置,点击运行按钮。 通过以上步骤,你就可以在 IntelliJ IDEA 中同时运行多个不同的 JVM 虚拟机实例。你可以通过创建多个配置,每个配置对应一个虚拟机实例,方便地管理和切换。这在需要模拟多个环境或进行并发调试时非常有用。 手把手教学 1.看看自己的项目 2.可能开始的时候啥也没有,就点Run Configuration Type 3.再点击Edit Configurations... 4.点击+号添加SpringBoot 5.主类选择一下,一般就一个,点他选了就行。 6.然后点击Modify Options 选择添加add VM Options 7.点击apply 再OK就有了!!! ———————————————— 原文链接:https://blog.csdn.net/m0_62645012/article/details/134628159
-
格式 以-D开头,多个jvm运行参数 用空格隔开 -Dproperty=Value 例如-Dfile.encoding=UTF-8 -Dspring.profiles.active=dev 注意: 1、如果-Dproperty=value的value中包含空格,可以将value使用引号引起来。例如:-Dmyname=“hello world”。 2、如果配置了-Dproperty=value参数,又在程序中使用了System.setProperty对同一个变量进行设置,那么以程序中的设置为准。 优先级关系 代码中的配置>Application中的配置>全局配置 ———————————————— 原文链接:https://blog.csdn.net/iijik55/article/details/126384345
-
背景 之前做项目配数据源信息,一般是把用户名,密码这些都放在一个properties文件中。最近做了个项目是把用户名密码配置在了web容器(tomcat)启动选项里,然后通过${key}注入到properties文件中。 由此产生很多疑问 容器的启动选项是怎么注入到properties文件中的。 容器的启动选项设置的属性的使用范围。 properties中配置的属性是怎么注入到spring配置文件中的。 properties中配置的属性的使用范围。 个人理解 (有问题请指教) 在网上找了很久,没有找到说清楚VM options是什么的相关帖子。我就自己理解一下吧。 写了一个demo,最后发现在VM options中配置的参数,可以通过${}占位符在项目的任何位置注入,比如spring的xml配置文件,properties文件以及通过@Value注入java文件中。 可以理解为容器的启动选项配置的属性是整个web容器的全局变量,可以在容器中的所有项目,所有项目中的所有文件中通过${key}引用到。 关于properties文件 紧接着我顺带深入理解了一下properties文件以及properties中定义的属性在spring中的作用域。 基础操作 首先properties就是一个定义键值对的文件,我们可以通过Properties类加载然后通过getProperty("key")来获取value,参考 通常做法: 但是我们用的最多的是在spring的相关配置中使用properties来收集一些配置属性方便修改。 在spring的xml配置文件中使用 来加载properties文件,然后在xml中用${key}来注入对应value,或者在java类属性上用@Value(${key})来注入对应value。 于是我又产生了一个疑问:在xml中引入的properties文件的作用域是什么,是当前xml文件?是spring容器?还是整个项目? 写了一个demo测了一下,发现xml中引入的properties的属性是容器级别的。比如springmvc系统中会有springmvc子容器和spring核心父容器两个容器,在springmvc.xml中引入的properties的属性只能在springmvc子容器中的bean以及同级别xml配置文件中获取到,而spring父容器中的bean则获取不到,反之亦然。 总结: 容器的启动选项是怎么注入到properties文件中的。解答:我们只需要配置容器启动选项,其他完全由容器实现和处理。 容器的启动选项设置的属性的使用范围。解答:容器中所有项目,项目中所有文件。 properties中配置的属性是怎么注入到spring配置文件中的。解答:我们只需要引入properties文件,其他由spring实现和处理 properties中配置的属性的使用范围。解答:属性引入的容器 ———————————————— 原文链接:https://blog.csdn.net/weixin_35186171/article/details/113548243
-
1:建议下载软件Everything 2:准备好Jetbrains家的相关IDE下载链接:jetbrains.com【安装过程不描述了】 3:建议下载付费的!没钱买正版可以去淘宝1r买激活码几乎全家桶适用,或者找人要 4:安装完后不要打开、否则自动生成配置文件在系统盘!先修改配置文件 二:配置文件 #这个配置可以减少默认在系统盘占用大量内存 1:在一个内存足够的磁盘创建文件夹【随便取,要英文】 2:搜索并打开文件idea.properties 3:分别有四个关键字且有对应的路径 idea.config.path、idea.system.path、idea.plugins.path、idea.log.path #找到第一步创建好的文件夹的路径、替换四个关键字对应的路径。 #注意不要有反斜杠\和中文,若修改当前行数的一行有#号记得删掉,否则为注释不做处理 4:配置成功三:按键配置 #此按键布局的移动键位和Vim编辑器操作有点类似【个人习惯】 #习惯后就不太需要鼠标了 1:打开IDE---Setting---Keymap---右边齿轮---Duplicated【复制一份新的按键布局】 2:搜索文件Windows copy.xml 3:将原来的Windows copy.xml 替换成我的按键布局 四:基础设置【便捷】 1:File---Settings---General---Change font size with Ctrl + Mouse Wheel 【打勾✔】 【Ctrl+鼠标滑轮可缩放大小】 2:File---Settings---Inspections---右边搜索Typo【取消勾勾】【或者是取消Spelling Error】 3:FIle---Settings---plguins---搜索Translation并下载【看个人需求】【这是翻译插件】 4:File---Settings---Editor---Font---Size设置26,字体我推荐JetBrains Mono 5:File---Settings---Appearance---自己看着设置,这里size我选择20。字体自选 6:设置背景 五:方法\函数模板设置【方便查看、看图】 #需要在【方法\函数】前加输入自己设置的模板快捷按键才会生成模板注释 二:点击 1:Abbreviation内我写的是/add代表我输入/add+Tab【在Expand With中设置】就会生成注释 2:这个符号$$里面的参数随便填写,包括前面的Name也是,填完后就可以选择Edit variables 3:填写完成后根据下图就可以翻译一下Expression内表达式的意思,比如date()就是日期然后Okay【不懂下载个百度翻译】 六:类模板设置#创建类文件后会自动生成模板注释 三:具体的模板的变量参数还得看官网给的文档、但是大部分都是相同的 ———————————————— 原文链接:https://blog.csdn.net/qq_38431616/article/details/120272815
-
Android Studio: ~/.config/Google/AndroidStudioPreview2022.3/studio64.vmoptions 其他IDE: ~/.config/JetBrains/RustRover2023.3/rustrover64.vmoptions ~/.config/JetBrains/PyCharm2023.3/pycharm64.vmoptions ~/.config/JetBrains/GoLand2023.1/goland64.vmoptions 以上是安装包默认的配置文件位置,如果设置以下环境变量,则会优先使用环境变量中指定的配置文件: JETBRAINSCLIENT_VM_OPTIONS=/home/jetbra/vmoptions/jetbrainsclient.vmoptions GOLAND_VM_OPTIONS=/home/jetbra/vmoptions/goland.vmoptions WEBSTORM_VM_OPTIONS=/home/jetbra/vmoptions/webstorm.vmoptions PHPSTORM_VM_OPTIONS=/home/jetbra/vmoptions/phpstorm.vmoptions WEBIDE_VM_OPTIONS=/home/jetbra/vmoptions/webide.vmoptions GATEWAY_VM_OPTIONS=/home/jetbra/vmoptions/gateway.vmoptions DATASPELL_VM_OPTIONS=/home/jetbra/vmoptions/dataspell.vmoptions APPCODE_VM_OPTIONS=/home/jetbra/vmoptions/appcode.vmoptions IDEA_VM_OPTIONS=/home/jetbra/vmoptions/idea.vmoptions STUDIO_VM_OPTIONS=/home/jetbra/vmoptions/studio.vmoptions CLION_VM_OPTIONS=/home/jetbra/vmoptions/clion.vmoptions DATAGRIP_VM_OPTIONS=/home/jetbra/vmoptions/datagrip.vmoptions RIDER_VM_OPTIONS=/home/jetbra/vmoptions/rider.vmoptions JETBRAINS_CLIENT_VM_OPTIONS=/home/jetbra/vmoptions/jetbrains_client.vmoptions PYCHARM_VM_OPTIONS=/home/jetbra/vmoptions/pycharm.vmoptions RUBYMINE_VM_OPTIONS=/home/jetbra/vmoptions/rubymine.vmoptions DEVECOSTUDIO_VM_OPTIONS=/home/jetbra/vmoptions/devecostudio.vmoptions ———————————————— 原文链接:https://blog.csdn.net/yinminsumeng/article/details/137033690
-
下拉列表(下拉框)可以确保用户仅从预先给定的选项中进行选择,这样不仅能减少数据输入错误,还能节省时间提高效率。在MS Excel中,我们可以通过 “数据验证” 提供的选项来创建下拉列表,但如果要在Java程序中通过代码实现这一功能,可能需要借助一些第三方库。本文将分享两种使用免费Java库在Excel中创建下拉列表的方法。操作Excel的免费Java控件:Free Spire.XLS for Java. (下载后手动引入jar包或者通过Maven仓库安装均可)方法一:基于字符串数组中的值来创建Excel下拉列表该方法是通过 Free Spire.XLS for Java 提供的 IDataValidation 接口下的 setValue() 方法先定义一个字符串数组作为列表项,然后再通过将 isSuppressDropDownArrow() 方法的参数设置为false 来应用下拉箭头。该方法就等同于在Excel “数据验证” 选项中的 “来源” 中直接输入一串内容作为列表项。Java代码:import com.spire.xls.*;import java.awt.*; public class ExcelDropdownList { public static void main(String[] args) { //创建Workbook对象 Workbook workbook = new Workbook(); //获取第一张工作表 Worksheet sheet = workbook.getWorksheets().get(0); //在指定单元格中添加文本 sheet.getCellRange("B2").setValue("职员"); sheet.getCellRange("B3").setValue("张三"); sheet.getCellRange("C2").setValue("部门"); //设置字体和单元格样式 sheet.getCellRange("B2:C2").getStyle().getFont().isBold(true); sheet.getCellRange("B2:C2").getStyle().getFont().setColor(Color.BLUE); sheet.getCellRange("B2:C3").getStyle().getFont().setSize(11); sheet.getCellRange("B2:C3").setRowHeight(18); sheet.getCellRange("B2:C3").setColumnWidth(12); //设置下拉列表的值 sheet.getCellRange("C3").getDataValidation().setValues(new String[]{"财务部", "采购部", "销售部", "行政部"}); //在指定单元格中创建下拉列表 sheet.getCellRange("C3").getDataValidation().isSuppressDropDownArrow(false); //保存结果文件 workbook.saveToFile("Excel下拉列表.xlsx", ExcelVersion.Version2013); }}方法二:基于单元格区域的内容来创建Excel下拉列表该方法是通过 Validation 类的 setDataRange() 方法指定一个单元格区域中的内容作为下拉列表的数据源。该方法更加灵活,创建后如果你想更新下拉列表的选项,直接更新单元格中的数据即可。效果如图:Java代码:import com.spire.xls.*;import java.awt.*; public class DropdownList { public static void main(String[] args) { //创建Workbook对象 Workbook workbook = new Workbook(); //获取第一张工作表 Worksheet sheet = workbook.getWorksheets().get(0); //在指定单元格中添加文本 sheet.getCellRange("B2").setValue("职员"); sheet.getCellRange("B3").setValue("张三"); sheet.getCellRange("C2").setValue("部门"); sheet.getCellRange("A11").setValue("财务部"); sheet.getCellRange("A12").setValue("采购部"); sheet.getCellRange("A13").setValue("销售部"); sheet.getCellRange("A14").setValue("行政部"); //设置字体和单元格样式 sheet.getCellRange("B2:C2").getStyle().getFont().isBold(true); sheet.getCellRange("B2:C2").getStyle().getFont().setColor(Color.BLUE); sheet.getCellRange("B2:C3").getStyle().getFont().setSize(11); sheet.getCellRange("B2:C3").setRowHeight(18); sheet.getCellRange("B2:C3").setColumnWidth(12); //将指定的单元格区域的内容作为数据源来创建下拉列表 sheet.getCellRange("C3:C4").getDataValidation().setDataRange(sheet.getCellRange("A11:A14")); //保存结果文件 workbook.saveToFile("Excel下拉列表2.xlsx", ExcelVersion.Version2013); }}转载自https://www.cnblogs.com/Yesi/p/18051989
-
在处理PDF文档时,有时需要为文档中的每一页添加页眉和页脚,以包含一些有用的信息,如文档标题、章节名称、日期、页码等。对于需要自动化处理的场景,或者需要在大量文档中添加一致的页眉和页脚,可以通过编程的方式来实现。本文将介绍如何使用Java为PDF文件添加页眉、页脚。所需工具:Free Spire.PDF for Java 免费库。可以点击链接下载最新版本并手动添加引用到你的Java项目中,同时也支持通过Mave仓库安装。方法简介:在以下示例中,我们用到了 PdfCanvas 类的DrawString()、DrawImage() 和 DrawLine() 方法,分别用于在PDF页面上指定位置绘制文本、图片和线条。如果要添加动态的信息如页码、页数、章节编号等,则可以使用Free Spire.PDF for Java提供的PdfPageNumberField、PdfPageCountField 和 PdfSectionNumberField 类,然后再使用Draw() 方法将其绘制到PDF页眉或页脚位置。示例代码:1. 使用Java在PDF中插入页眉import com.spire.pdf.PdfDocument;import com.spire.pdf.PdfPageBase;import com.spire.pdf.graphics.*; import java.awt.*; public class PDFHeader { public static void main(String[] args) { //加载PDF文档 PdfDocument pdf = new PdfDocument(); pdf.loadFromFile("考核.pdf"); //加载图片 PdfImage headerImage = PdfImage.fromFile("logo.jpg"); //获取图片宽度 float width = headerImage.getWidth(); PdfUnitConvertor unitCvtr = new PdfUnitConvertor(); float pointWidth = unitCvtr.convertUnits(width, PdfGraphicsUnit.Pixel, PdfGraphicsUnit.Point); //指定页眉文本 String headerText = "年度绩效考核\nAAA有限责任公司"; //创建字体 PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("宋体", Font.BOLD, 12),true); //创建画笔 PdfBrush brush = PdfBrushes.getRed(); PdfPen pen = new PdfPen(PdfBrushes.getBlack(), 1.0f); //遍历所有PDF页面 for (int i = 0; i < pdf.getPages().getCount(); i++) { //获取指定页面 PdfPageBase page = pdf.getPages().get(i); //在顶部空白区域绘制图像 page.getCanvas().drawImage(headerImage, page.getActualSize().getWidth() - pointWidth - 55, 20); //在顶部空白区域绘制文本 page.getCanvas().drawString(headerText, font, brush, 55, 30); //在顶部空白区域绘制一条线 page.getCanvas().drawLine(pen, new Point(55, 70), new Point((int)page.getActualSize().getWidth() - 55, 70)); } //保存生成PDF文件 pdf.saveToFile("PDF页眉.pdf"); pdf.dispose(); }}以上代码遍历了PDF文档的所有页面,并在每一页的页眉位置添加了文本、图片和分隔线,运行后效果图如下:2. 使用Java在PDF中插入页脚import com.spire.pdf.PdfDocument;import com.spire.pdf.PdfPageBase;import com.spire.pdf.automaticfields.PdfCompositeField;import com.spire.pdf.automaticfields.PdfPageCountField;import com.spire.pdf.automaticfields.PdfPageNumberField;import com.spire.pdf.graphics.*; import java.awt.*;import java.awt.geom.Dimension2D;import java.awt.geom.Point2D; public class PDFFooter { public static void main(String[] args) { //加载PDF文档 PdfDocument pdf = new PdfDocument(); pdf.loadFromFile("考核.pdf"); //创建字体 PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("宋体", Font.BOLD, 12),true); //创建画笔 PdfBrush brush = PdfBrushes.getBlack(); PdfPen pen = new PdfPen(PdfBrushes.getBlack(), 1.0f); //创建页码字段 PdfPageNumberField pageNumberField = new PdfPageNumberField(); //创建页数字段 PdfPageCountField pageCountField = new PdfPageCountField(); //创建一个复合字段,将页数字段和页码字段合并为一个字符串 PdfCompositeField compositeField = new PdfCompositeField(font, brush, "第{0}页/共{1}页", pageNumberField, pageCountField); //获取文本尺寸 Dimension2D fontSize = font.measureString(compositeField.getText()); //获取页面尺寸 Dimension2D pageSize = pdf.getPages().get(0).getSize(); //设置复合字段的位置 compositeField.setLocation(new Point2D.Double((pageSize.getWidth() - fontSize.getWidth())/2, pageSize.getHeight() - 45)); //遍历PDF页面 for (int i = 0; i < pdf.getPages().getCount(); i++) { //获取指定页 PdfPageBase page = pdf.getPages().get(i); //在底部空白区域绘制一条线 page.getCanvas().drawLine(pen, new Point(72, (int) (pageSize.getHeight() - 60)), new Point((int)pageSize.getWidth() - 72, (int) pageSize.getHeight()- 60)); //在底部空白区域绘制复合字段 compositeField.draw(page.getCanvas()); } //保存生成PDF文件 pdf.saveToFile("PDF页脚.pdf"); pdf.dispose(); }}以上代码遍历了PDF文档的所有页面,并在每一页的页脚位置添加了对应的页码、页数信息以及一条分隔线,运行后效果图如下:小结:在不破坏PDF文档布局的情况下,我们可以使用Free Spire.PDF for Java免费库将所需的元素绘制到PDF页面顶部和底部的指定位置来生成自定义页眉页脚,提高PDF文档的可读性和专业性。转载自https://www.cnblogs.com/Yesi/p/18094584
-
Action模型概述Action模型系本人基于Java语言研发的一套中间件。作为一个中间件,其在理论上的最大亮点在于:在Action模型提供的可串行化(Serializable)这一事务隔离级别下,可以达到读未提交(Read Uncommitted)这一事务隔离级别的并发性能(这就要求位于Action模型之下的DBMS仅提供读未提交的事务隔离级别即可)。事实上,Action模型向上层(即业务层)总共提供三种事务隔离级别:可串行化、混合可串行化(此隔离级别属于本人自创)、严格可串行化(Strict Serializable)。也就是说,Action模型最低的事务隔离级别就是可串行化,并且在此事务隔离级别下可以达成读未提交一级的并发性能。这就真正达成了一种鱼和熊掌可以得兼的效果。Action模型在实践上的最大亮点在于如下三点:- 无需考虑并发的并发模型(Concurrency);- 无需时间输入的时间模型(Time);- N元关联也支持Qualifier的关联模型(Association)。并且以上所有亮点都是以免程序员的方式实现。应用Action模型的步骤如下:- 应用一个增强型UML模型编辑器(注意这里不是传统的UML,而是经过扩展后的增强型UML,传统的UML由于在这一方面的表达能力不足,因此无法但此重任)进行建模;- 将建好的模型自动输出为XML文件;- 应用代码自动生成器,以上一步的XML文件作为输入,自动生成完整的中间层代码API(也包含SQL代码);当Action模型的代码生成完毕之后,有三种应用途径:- 由程序员进行业务代码的编写工作;- 由低代码/无代码平台构建业务代码;- 由AIGC生成业务代码。无论那一种途径,只要在业务代码中调用前面生成的中间层代码API,就可以使得开发的系统自动具有上面所描述的几个特征,例如,无需考虑并发、无需考虑时间输入、无需考虑低级别事务隔离级别所带来的种种缺点、等等。我之所以能够一个人进行Action模型的研发,代码自动生成技术(其属于MDA,即模型驱动架构,的一部分)起了非常关键的作用。否则,仅凭我一人之力,单单是百分之百正确率的敲代码的工作量就是一项个人难以完成的任务。Action模型既非来自开源软件,自身也未开源,属于本人自创的一套软件体系。目前已经适配MySQL和MSSQL。Action模型的一个重要特性是支持强一致性(即读操作一定能够读取到在其之前最近的写操作所写入的数据),单机版本的Action模型对此没有任何问题,一主多从版本的Action模型对此也没有任何问题。Action模型的另一个重要特性是原生地具有防篡改的特性。只要位于其下的DBMS能够保证无法直接对数据库表文件进行篡改,就可以保证应用Action模型的系统无法对系统中的任何数据进行篡改。当前流行的微服务架构比较适合高并发和简单业务场景的系统,而Action模型则适合于中高并发和复杂业务场景的系统。因此微服务架构比较适合于电商等应用,而Action模型则比较适合于金融、ERP、OA等企业级应用。Action模型与当前比较流行的低代码/无代码开发平台的侧重点各不相同:Action模型因为是一个中间件,因此侧重于后台底层代码的自动生成,而当前的低代码/无代码开发平台最弱的地方就在于这一部分。因此Action模型如果与当前的低代码/无代码开发平台进行结合,将可以产生相得益彰的效果。当然,如果不与当前的低代码/无代码开发平台相结合,则也可以直接利用Action模型进行业务系统的开发,只是现在业务代码的开发需要程序员来完成而已。Action模型与当前大热的AIGC之间的关系:由于Action模型在中间层就提供了并发、时间、关联的支持,因此可以大大降低AIGC生成代码的难度,因为现在AIGC仅需考虑业务逻辑,即专注于业务代码的生成。就以并发为例,如果没有Action模型,如果你对AIGC说基于中间层提供的API生成业务代码,并加上考虑并发和不考虑并发这两个选项,则不考虑并发所生成的代码的质量和考虑并发所生成的代码的质量是截然不同的。这个大家在最近国内比较热的大模型Kimi上试试看就知道了。众所周知,芯片的生产包含制造、封装和测试这三大步骤,如果我们将Action模型比作一个芯片,则目前为止其核心模块的制造过程已经基本完成,就剩下封装和测试这两大步骤还需完善。这里所谓的封装即是Action模型与各种框架的集成。开始时我使用的框架是Struts2,但是目前已经转到Spring Boot,转到后者的主要原因是其比较简洁,这样就可以使开发的工作量主要用在Action模型上。最早的代码开发环境和测试环境如下:Windows + JDK8 + EclipseSDK + MSSql2012Dev + Struts2 + Tomcat和JBoss/Wildfly;后来新增的代码开发和测试环境如下:Ubuntu + OpenJDK17 + Eclipse202303 + MySql + Spring Boot + Tomcat;这里所谓的测试就是软件测试。我已经针对Action模型进行了一些测试,不过由于人力所限,虽然通过这些测试发现了不少的Bug,也解决了这些Bug,但是仍旧可能会存在一些Bug。可以通过编写大量应用Action模型的实例的办法对Action模型进行进一步的测试,而这是单靠我一个人无法完成的。这就意味着,实现Action模型的三个环节中难度最大,重要性最高的制造环节已经完成,再往后就是工作量的问题。实际上,在我编写的一个测试用例中,同时开450个Runnable链(可以将1个Runnable链视为1个事务),其中共有三种类型的长短事务,每种150个,并且将其运行在一台只有16线程CPU的笔记本上,可以确保这其中既不会有死锁,也不会有数据竞争发生,这里的技术含量就无需赘述了。以Action模型为核心的一系列技术基本上都由本人独立研发而成,本人承担了百分之九十九的工作量,并具有百分之一百的知识产权,因此完全可以采用双方都认可的任何方式进行合作。如果对这套中间件感兴趣的话,我还可以提供更详细的资料,并且可以到贵处进行现场演示和交流。
-
JAVA实现树的遍历
-
1.日志系统概述 关于日志系统,其要支撑的核心能力无非是日志的存储以及查看,最好的查看方式当然是实现可视化。目前市面上有成熟的解决方案——ELK,即elastic search+logstash+kibana。前文中我们已经聊过了ELK这条线,本文主要就是基于ELK并在其中加一个MQ作为中间层来流量削峰、异步写日志。 这里首先要声明的是,虽然本文在日志系统中使用到了MQ,但MQ真的是必要的嘛? 这个要看系统的体量了。除非是超大型的分布式架构,服务上百个并且并发量较高,才会考虑用MQ来做一层缓存从而来降低IO压力。如果不是上述情况的话是没有必要上MQ来做一个中间层的。日志作为系统中掺入的"沙子",其量本来就不会很大,一次API调用平均能产生一条日志吗?其实是不见的是吧。所以就这点数据量上MQ这种吞吐量的中间层简直就是杀鸡用牛刀,过度设计,徒增了系统的复杂度了。MQ更多的时候是拿来做移步任务或者定时任务的,用来做业务上的流量削峰或者异步的去做些事情。比如异步的下订单、订单超时取消等。绝大多数时候我们的日志系统的架构,直接让存储去直面日志IO都是能轻轻松松顶得住的。所谓的让存储去直面日志的IO是什么意思?就是比如我走了ELK这条线,那么就直接讲日志往es里面丢就对了。ELK这么用前面已经有文章介绍过了。本文还是聊一聊假设真的到了很极限的中间需要引入MQ的情况。 ELK的搭建这里就不赘述了,前面有文章详细聊过: https://bugman.blog.csdn.net/article/details/135964825?spm=1001.2014.3001.5502 https://bugman.blog.csdn.net/article/details/136017853?spm=1001.2014.3001.5502 https://bugman.blog.csdn.net/article/details/136066171?spm=1001.2014.3001.5502 这里我们只需要关注几个点: 应用的日志如何推到mq中 logstash如何去取mq中存放的日志 2.环境搭建 ELK相关内容: MQ我们选择rabbitMQ,作为一个开箱即食的MQ,rabbitMQ的下载安装网上文章车载斗量,此处就不赘述了。 3.应用如何推日志到MQ 写日志肯定是JAVA的日志框架来负责的,前面有文章已经详细的介绍了JAVA的日志框架: 【JAVA日志框架】JUL,JDK原生日志框架详解。_jul jdk-CSDN博客 JAVA的日志框架总的来说架构都是大同小异的,都是由不同的appender(有的里面叫handler其实都是一个东西)来向不同的地方写日志: 既然要往rabbitMQ里面写日志,那当然就要一个rabbitMQ的appender了。这个appender在哪里?在rabbitMQ的JAVA API依赖中: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> </dependency> 然后配置一下日志框架的配置文件即可,这里我们以spring boot默认的日志框架logback为例,在其配置文件中配置好rabbitMQ的appender即可: <configuration> <!-- 定义 RabbitMQ 连接 --> <appender name="RABBIT" class="com.github.logback.amqp.AmqpAppender"> <host>localhost</host> <!-- RabbitMQ 主机地址 --> <port>5672</port> <!-- RabbitMQ 端口 --> <username>guest</username> <!-- RabbitMQ 用户名 --> <password>guest</password> <!-- RabbitMQ 密码 --> <exchange>logs</exchange> <!-- RabbitMQ 交换机 --> <routingKey>logstash</routingKey> <!-- RabbitMQ 路由键 --> <declareExchange>true</declareExchange> <!-- 是否声明交换机 --> <exchangeType>fanout</exchangeType> <!-- 交换机类型 --> <durable>true</durable> <!-- 是否持久化消息 --> <applicationId>myApplication</applicationId> <!-- 应用程序标识 --> <!-- 其他可选配置 --> <!--<declareQueue>true</declareQueue>--> <!--<queue>logQueue</queue>--> <!--<declareBinding>true</declareBinding>--> </appender> <!-- 定义日志输出格式 --> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern> </layout> <!-- 根日志输出到 RabbitMQ --> <root level="INFO"> <appender-ref ref="RABBIT"/> </root> </configuration> 4.logstash如何去MQ中取日志 logstash的input可以理解为插件,既然是插件当然就有很多中类型,其中就包括rabbitMQ的(自然也有其它的),下面是logstash从MQ中取数据然后推给es的一份示例: input { rabbitmq { host => "localhost" # RabbitMQ 主机地址 port => 5672 # RabbitMQ 端口 user => "guest" # RabbitMQ 用户名 password => "guest" # RabbitMQ 密码 queue => "logQueue" # RabbitMQ 队列名 durable => true # 是否持久化队列 ack => true # 是否需要手动确认消息 threads => 1 # 线程数 } } output { stdout { codec => rubydebug } # 输出到控制台,可选 elasticsearch { hosts => ["localhost:9200"] # Elasticsearch 主机地址 index => "logstash-%{+YYYY.MM.dd}" # Elasticsearch 索引名 } } 5.如何兼顾分布式链路追踪 这里顺带讨论一个问题,就是在ELK体系中如何去实现分布式链路跟踪。分布式链路跟踪相关内容前面有文章详细讨论过: https://bugman.blog.csdn.net/article/details/135258207?spm=1001.2014.3001.5502 https://bugman.blog.csdn.net/article/details/135258207?spm=1001.2014.3001.5502 其实在ELK中实现分布式链路追踪的方式很简单,思路如下: 仍然在应用侧上链路追踪技术来统一日志格式,然后要进行查询追踪的时候直接使用Kibana的搜索和过滤功能来仅显示与特定跟踪ID或请求ID相关的日志消息,或者利用Kibana的图表功能,将日志数据与分布式追踪数据结合起来,创建可视化的图表和仪表板。你可以根据需要显示请求的整个路径、每个步骤的响应时间、错误率等指标。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/Joker_ZJN/article/details/136357635
-
请问按照要求修改了java目录为src\com\huawei\codecraft后,提交zip文件依然提示程序编译异常
-
大家好,二月的合集又来了,本次涵盖了java,linux,spirng诸多内容供大家学习。 1.Vue中的$nextTick有什么作用?【转】 https://bbs.huaweicloud.com/forum/thread-02109144317537776031-1-1.html 2.基于Python的地图绘制教程【转】 https://bbs.huaweicloud.com/forum/thread-0240144319944756030-1-1.html 3.hcache 介绍(1)--Ehcache 功能特性 【转】 https://bbs.huaweicloud.com/forum/thread-0268144320319800023-1-1.html 4.Java 操作 XML(1)--DOM 方式处理 XML【转】 https://bbs.huaweicloud.com/forum/thread-02109144320463478034-1-1.html 5.Java操作XML(3)--StAX方式处理XML 【转】 https://bbs.huaweicloud.com/forum/thread-0240144320615655031-1-1.html 6.Java操作XML(4)--使用woodstox处理XML【转】 https://bbs.huaweicloud.com/forum/thread-0270144320690142025-1-1.html 7.Java操作XML(5)--使用JDOM处理XML【转】 https://bbs.huaweicloud.com/forum/thread-0240144320817429032-1-1.html 8.Java操作XML(6)--使用dom4j处理XML【转】 https://bbs.huaweicloud.com/forum/thread-02101144320893290020-1-1.html 9.基于原生Go语言开发一个博客系统【转】 https://bbs.huaweicloud.com/forum/thread-0269144558086016006-1-1.html 10.详解Golang如何使用Debug库优化代码【转】 https://bbs.huaweicloud.com/forum/thread-0225144558556243005-1-1.html 11.Python3中的指针你了解吗【转】 https://bbs.huaweicloud.com/forum/thread-0274144558593208011-1-1.html 12.Python绘图实现坐标轴共享与复用详解【转】 https://bbs.huaweicloud.com/forum/thread-02104144558721772010-1-1.html 13.使用Golang开发一个简易版shell【转】 https://bbs.huaweicloud.com/forum/thread-0226144559187797004-1-1.html 14.python导入其它py文件的实现步骤【转】 https://bbs.huaweicloud.com/forum/thread-0284144559442791006-1-1.html 15.Python property函数的具体使用【转】 https://bbs.huaweicloud.com/forum/thread-0259144559705810008-1-1.html 16.正则表达式的神奇世界之表达、匹配和提取全解析【转】 https://bbs.huaweicloud.com/forum/thread-02104144569438876012-1-1.html 17.正则去除中括号(符号)及里面包含的内容(最新推荐)【转】 https://bbs.huaweicloud.com/forum/thread-0226144569604407008-1-1.html 18.Javaweb项目启动Tomcat常见的报错解决方案【转】 https://bbs.huaweicloud.com/forum/thread-0274144571948983013-1-1.html 19.SpringBoot+Vue前后端分离实现审核功能的示例【转】 https://bbs.huaweicloud.com/forum/thread-0269144572025869007-1-1.html 20.Java中Collections.sort()排序方法举例详解【转】 https://bbs.huaweicloud.com/forum/thread-0269144572170830008-1-1.html 21.Java中回调函数 (callback) 及其实际应用场景【转】 https://bbs.huaweicloud.com/forum/thread-0259144572260172012-1-1.html 22.Redis实现商品秒杀的示例代码【转】 https://bbs.huaweicloud.com/forum/thread-0274144574350854015-1-1.html
推荐直播
-
手把手教你实现mini版TinyVue组件库
2024/04/17 周三 16:30-18:00
阿健 华为云前端开发DTSE 技术布道师
在前端Web开发过程中,跨版本兼容性问题是一个普遍存在的挑战。为了解决这些痛点,OpenTiny推出跨端、跨框架、跨版本组件库TinyVue。本期直播聚焦于华为云的前端开源组件库TinyVue,通过mini版TinyVue的代码实践与大家共同深入解读Vue2/Vue3不同版本间的差异。这对于提升用户体验,减低维护成本,提升开发者技术洞察有重要意义。
回顾中 -
如何快速入驻O3使能伙伴服务作业平台
2024/04/18 周四 16:00-16:40
红喜 O3伙伴服务工作台技术总架构师
本期邀请O3伙伴服务工作台技术总架构师,讲解O3伙伴服务工作台的设计理念,及演示工作台关键能力与价值点,带你2步快速入驻工作台。O3伙伴服务工作台,具备在线Online、开放Open、协同Orchestration的特征,作为伙伴服务的统一入口,支持伙伴以租户方式入驻,涵盖伙伴工程师、管理者等多角色,是一个以伙伴服务领域全旅程作业为中心,整合华为服务各专业领域能力,开放共享的一站式作业平台。
去报名
热门标签