首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java 集合中常见 checkForComodification()方法的作用? modCount和expectedModCount作用?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40254498/article/details/81386920 主要是用来实现fail-fast机制 有两个线程(线程A,线程B),其中线程A负责遍历list、线程B修改list。 -线程A在遍历list过程的某个时候(此时expectedModCount = modCount=N),线程启动, 同时线程B增加一个元素,这是modCount的值发生改变(modCount + 1 = N + 1)。 线程A继续遍历执行next方法时, 通告checkForComodification方法发现expectedModCount = N , 而modCount = N + 1,两者不等, 这时就抛出ConcurrentModificationException 异常,从而产生fail-fast机制。 /** * 当前取的是 JDK1.8 ArrayList中的代码 */ /** * The number of times this list has been <i>structurally modified</i>. * Structural modifications are those that change the size of the * list, or otherwise perturb it in such a fashion that iterations in * progress may yield incorrect results. * * <p>This field is used by the iterator and list iterator implementation * returned by the {@code iterator} and {@code listIterator} methods. * If the value of this field changes unexpectedly, the iterator (or list * iterator) will throw a {@code ConcurrentModificationException} in * response to the {@code next}, {@code remove}, {@code previous}, * {@code set} or {@code add} operations. This provides * <i>fail-fast</i> behavior, rather than non-deterministic behavior in * the face of concurrent modification during iteration. * * <p><b>Use of this field by subclasses is optional.</b> If a subclass * wishes to provide fail-fast iterators (and list iterators), then it * merely has to increment this field in its {@code add(int, E)} and * {@code remove(int)} methods (and any other methods that it overrides * that result in structural modifications to the list). A single call to * {@code add(int, E)} or {@code remove(int)} must add no more than * one to this field, or the iterators (and list iterators) will throw * bogus {@code ConcurrentModificationExceptions}. If an implementation * does not wish to provide fail-fast iterators, this field may be * ignored. */ protected transient int modCount = 0; 在父类AbstractList中定义了一个int型的属性:modCount protected transient int modCount = 0; 在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。 AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回: public Iterator iterator() { return new Itr(); } Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。 int expectedModCount = modCount; 注:内部成员类Itr也是ArrayList类的一个成员,它可以访问所有的AbstractList的属性和方法。理解了这一点,Itr类的实现就容易理解了。 在Itr.hasNext()方法中: public boolean hasNext() { return cursor != size; } 调用了AbstractList的size,比较当前光标位置是否越界。 public Object next() { try { Object next = get(cursor); checkForComodification(); lastRet = cursor++; return next; } catch(IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } /** * 在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操作 * 这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。 * 在AbstractList中,使用了一个简单的机制来规避这些风险。 * 这就是modCount和expectedModCount的作用所在 */ final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }

优秀的个人博客,低调大师

打包报错 Error: java.util.concurrent.ExecutionException: com.android.build...

骚年,还记得当初为这个上刀山下火海,抓破脑袋都搞定不了的问题吗? 俗话说的好: 有问题找百度,教程都给你了 image.png 但是,这玩意儿是真的,百度出来不好使啊。 image.png 有无数个博客教你这么做吧? 不好意思过时了,2018年已经废除这个东西了。 其实AAPT2的错误并不复杂,90%以上都是你的资源文件出了问题,我们可以先尝试在app下面的build中加上两个配置属性: android{ //关闭AS校验我们的资源文件,或者说是PNG等图片 aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false 如果这样以来你发现你可以正常编译或者打包成功,那么肯定是你资源的问题,请好好排查。 gradle ar 这个命令也许会对你有帮助。 这两个属性建议仅仅是让你排查问题,希望不要把它当做解决方法而去使用,毕竟带着问题上线是件不好的事情;对吧。 具体的问题还是需要你看日志的,希望对你有所帮助。thanks。

优秀的个人博客,低调大师

Java---------- LeetCode——746. 使用最小花费爬楼梯

这个是最让我郁闷的我操,我用了一上午的时间来实现它,当然了刚开始我并没有用动态规划,我用自己的方式来实现,其实我不知道要用动态规划来实现它,写了一上午,最后发现,在LeetCode测试时,有些数据通不过啊,于是乎我就打补丁,打打补丁,最后发现实在打不下去补丁了,就于是乎用动态规划实现,但是我不会动态规划啊,那怎么办,学啊,我学了一会儿,感觉够用了, public static int minPay(int[] number) { // 我这个不怎么理解,现在理解了;原来这里多设置数组长度是为了fly(4)后边的做准备【表情】额 int[] fly = new int[number.length+1]; fly[0] = number[0]; fly[1] = number[1]; // 这个我也不怎么理解,这个number.length原来是为了达到数组长度时,加0直接输出啊。 for (int i = 2; i <=number.length ; i++) { int current = i == number.length ? 0 : number[i]; // 这个依然是核心代码,依然是看前边的怎么执行 fly[i] = Math.min(fly[i-1],fly[i-2])+current; } return fly[number.length]; }

优秀的个人博客,低调大师

让你一看就懂的快速排序算法(Java

快速排序 你也许会被快速排序的文章弄得迷迷糊糊,其实大体上去看,快速排序就一步:找个数做基准数,把小于它的数移到它左边,把大于它的数移到它右边。这句话是核心。然后我们只需要让基准数左边的重复上面的步骤,让基准数右边的再重复上面的步骤就完了。 比如我们有一个数组: int[] nums = {5, 2, 6, 8, 4, 7, 9, 1}; 快速排序的思想就是使用递归,其实使用递归并不是多么复杂,在理解算法的思想后,只需要关注算法中重复的步骤,那就是递归的核心代码。 比如快速排序的算法思想,大体代码如下: public void quick(int left, int right) { /* * 给这段代码起个名字为:基准校验 * 把小于基准数的移到左边,把大于基准数的移到右边 */ quick(left, now); //继续处理左边的 quick(now, right); //继续处理右边的 } 经过一遍基准校验,我们就找到了该基准数在完全排序后的正确位置! 大体算法的流程图: 写出上面的大体算法步骤,就表示我们已经有了雏形,现在该如何实现找个数做基准数,把小于它的数移到它左边,把大于它的数移到它右边呢? 排除不满足的情况: //已经不满足条件就代表可以不用递归了 if (left > right) { return; } 我们可以定义两个指针,用于遍历数组: int start = left;//起点下标 int end = right;//终点下标 再找一个基准数: int temp = nums[left];//把第一个数作为基准点 遍历代码: /*如果左右指针还没有走到一起,代表还有位置没有遍历*/ while (start != end) { //右指针先走,找到小于基准数的停止 while (start < end && nums[end] >= temp) { end--; //这是往左移动指针 } //左指针后走,找到大于基准数的停止 while (start < end && nums[start] <= temp) { start++; //这是往右移动指针 } //如果左右指针在未相遇时都找到了目标,则交换位置 if (start < end) { int i = nums[start]; nums[start] = nums[end]; nums[end] = i; } //左右指针走到一起,则遍历结束 } //把基准数与该点交换位置,因为这就是基准数的正确位置 nums[left] = nums[start]; nums[start] = temp; 如果还是不太清楚,不如自己动手试试! 拷贝完整代码: //定义一个数组 static int[] nums = {5, 2, 6, 8, 4, 7, 9, 1}; static int n = nums.length - 1; /** * 递归的数据结构就是栈 * left right代表该段数组的起点和终点 */ public void quick(int left, int right) { //已经不满足条件就可以不用递归了 if (left > right) { return; } //定义俩指针 用于移动 int start = left;//起点下标 int end = right;//终点下标 int temp = nums[left];//把第一个数作为基准点 pri(left, right);//打印此时的结果,不用在意 while (start != end) { //如果左右指针还没有走到一起,代表还有位置没有遍历 while (start < end && nums[end] >= temp) { //右指针先走,找到小于基准数的停止 end--; //这是往左在移动指针 } while (start < end && nums[start] <= temp) { //左指针后走,找到大于基准数的停止 start++; //这是往右在移动指针 } if (start < end) { //如果左右指针在未相遇时都找到了目标,则交换位置 int i = nums[start]; nums[start] = nums[end]; nums[end] = i; } } //此时的left和right走到了一起 //把基准数与该点交换位置 nums[left] = nums[start]; nums[start] = temp; prin(start);//打印输出,不用在意 //以上代码的作用就是把小于基准数的移到左边,把大于基准数的移到右边 quick(left, start - 1); //继续处理左边的,这里是一个递归的过程 quick(start + 1, right); //继续处理右边的 ,这里是一个递归的过程 } /** * 主程序入口 */ public static void main(String[] args) { new Test().quick(0, n); } /** * 以下代码忽略即可,用于打印输出 */ private void pri(int start, int end) { StringBuffer s = new StringBuffer(); s.append("对数组 ["); while (start <= end) { s.append(nums[start] + " "); start++; } s.append("]"); s.append(" 排序"); System.out.print(s); } private void prin(int j) { StringBuffer s = new StringBuffer(); s.append(", 排序后 ["); int start = 0; while (start <= n) { if (start == j) { s.append("(" + nums[start] + ") "); } else { s.append(nums[start] + " "); } start++; } s.append("]"); s.append(" "); System.out.println(s); } 打印输出: 对数组 [5 2 6 8 4 7 9 1 ] 排序, 排序后 [4 2 1 (5) 8 7 9 6 ] 对数组 [4 2 1 ] 排序, 排序后 [1 2 (4) 5 8 7 9 6 ] 对数组 [1 2 ] 排序, 排序后 [(1) 2 4 5 8 7 9 6 ] 对数组 [2 ] 排序, 排序后 [1 (2) 4 5 8 7 9 6 ] 对数组 [8 7 9 6 ] 排序, 排序后 [1 2 4 5 6 7 (8) 9 ] 对数组 [6 7 ] 排序, 排序后 [1 2 4 5 (6) 7 8 9 ] 对数组 [7 ] 排序, 排序后 [1 2 4 5 6 (7) 8 9 ] 对数组 [9 ] 排序, 排序后 [1 2 4 5 6 7 8 (9) ]

优秀的个人博客,低调大师

JAVA实现QRCode的二维码生成以及打印

喜欢的朋友可以关注下,粉丝也缺。 不说废话了直接上代码 注意使用QRCode是需要zxing的核心jar包,这里给大家提供下载地址 https://download.csdn.net/download/dsn727455218/10515340 1.二维码的工具类 public class QR_Code { private static int BLACK = 0x000000; private static int WHITE = 0xFFFFFF; /** * 1.创建最原始的二维码图片 * * @param info * @return */ private BufferedImage createCodeImage(CodeModel info) { String contents = info.getContents();//获取正文 int width = info.getWidth();//宽度 int height = info.getHeight();//高度 Map<EncodeHintType, Object> hint = new HashMap<>(); hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置二维码的纠错级别【级别分别为M L H Q ,H纠错能力级别最高,约可纠错30%的数据码字】 hint.put(EncodeHintType.CHARACTER_SET, info.getCharacter_set());//设置二维码编码方式【UTF-8】 hint.put(EncodeHintType.MARGIN, 0); MultiFormatWriter writer = new MultiFormatWriter(); BufferedImage img = null; try { //构建二维码图片 //QR_CODE 一种矩阵二维码 BitMatrix bm = writer.encode(contents, BarcodeFormat.QR_CODE, width, height + 5, hint); int[] locationTopLeft = bm.getTopLeftOnBit(); int[] locationBottomRight = bm.getBottomRightOnBit(); info.setBottomStart(new int[] { locationTopLeft[0], locationBottomRight[1] }); info.setBottomEnd(locationBottomRight); int w = bm.getWidth(); int h = bm.getHeight(); img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { img.setRGB(x, y, bm.get(x, y) ? BLACK : WHITE); } } } catch (WriterException e) { e.printStackTrace(); } return img; } /** * 2.为二维码增加logo和二维码下文字 logo--可以为null 文字--可以为null或者空字符串"" * * @param info * @param output */ private void dealLogoAndDesc(CodeModel info, OutputStream output) { //获取原始二维码图片 BufferedImage bm = createCodeImage(info); //获取Logo图片 File logoFile = info.getLogoFile(); int width = bm.getWidth(); int height = bm.getHeight(); Graphics g = bm.getGraphics(); //处理logo if (logoFile != null && logoFile.exists()) { try { BufferedImage logoImg = ImageIO.read(logoFile); int logoWidth = logoImg.getWidth(); int logoHeight = logoImg.getHeight(); float ratio = info.getLogoRatio();//获取Logo所占二维码比例大小 if (ratio > 0) { logoWidth = logoWidth > width * ratio ? (int) (width * ratio) : logoWidth; logoHeight = logoHeight > height * ratio ? (int) (height * ratio) : logoHeight; } int x = (width - logoWidth) / 2; int y = (height - logoHeight) / 2; //根据logo 起始位置 和 宽高 在二维码图片上画出logo g.drawImage(logoImg, x, y, logoWidth, logoHeight, null); } catch (Exception e) { e.printStackTrace(); } } //处理二维码下文字 String desc = info.getDesc(); if (!"".equals(desc)) { try { //设置文字字体 int whiteWidth = info.getHeight() - info.getBottomEnd()[1]; Font font = new Font("宋体", Font.PLAIN, info.getFontSize()); int fontHeight = g.getFontMetrics(font).getHeight(); //计算需要多少行 int lineNum = 1; int currentLineLen = 0; for (int i = 0; i < desc.length(); i++) { char c = desc.charAt(i); int charWidth = g.getFontMetrics(font).charWidth(c); if (currentLineLen + charWidth > width) { lineNum++; currentLineLen = 0; continue; } currentLineLen += charWidth; } int totalFontHeight = fontHeight * lineNum; int wordTopMargin = 4; BufferedImage bm1 = new BufferedImage(width, height + totalFontHeight + wordTopMargin - whiteWidth, BufferedImage.TYPE_INT_RGB); Graphics g1 = bm1.getGraphics(); if (totalFontHeight + wordTopMargin - whiteWidth > 0) { g1.setColor(Color.WHITE); g1.fillRect(0, height, width, totalFontHeight + wordTopMargin - whiteWidth); } g1.setColor(new Color(BLACK)); g1.setFont(font); int startX = (78 - (12 * desc.length())) / 2; g1.drawImage(bm, 0, 0, null); width = info.getBottomEnd()[0] - info.getBottomStart()[0]; height = info.getBottomEnd()[1] + 1; currentLineLen = 0; int currentLineIndex = 0; int baseLo = g1.getFontMetrics().getAscent(); for (int i = 0; i < desc.length(); i++) { String c = desc.substring(i, i + 1); int charWidth = g.getFontMetrics(font).stringWidth(c); if (currentLineLen + charWidth > width) { currentLineIndex++; currentLineLen = 0; g1.drawString(c, currentLineLen + startX - 5, -5 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); currentLineLen = charWidth; continue; } g1.drawString(c, currentLineLen + startX - 5, -5 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); currentLineLen += charWidth; } //处理二维码下日期 String date = info.getDate(); g1.drawString(date, 5, 6 + height + baseLo + fontHeight * (currentLineIndex) + wordTopMargin); g1.dispose(); bm = bm1; } catch (Exception e) { e.printStackTrace(); } } try { ImageIO.write(bm, info.getFormat(), output); } catch (Exception e) { e.printStackTrace(); } } /** * 3.创建 带logo和文字的二维码 * * @param info * @param file */ public void createCodeImage(CodeModel info, File file) { File parent = file.getParentFile(); if (!parent.exists()) parent.mkdirs(); OutputStream output = null; try { output = new BufferedOutputStream(new FileOutputStream(file)); dealLogoAndDesc(info, output); output.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 3.创建 带logo和文字的二维码 * * @param info * @param filePath */ public void createCodeImage(CodeModel info, String filePath) { createCodeImage(info, new File(filePath)); } /** * 4.创建 带logo和文字的二维码 * * @param filePath */ public void createCodeImage(String contents, String filePath) { CodeModel codeModel = new CodeModel(); codeModel.setContents(contents); createCodeImage(codeModel, new File(filePath)); } /** * 5.读取 二维码 获取二维码中正文 * * @param input * @return */ public String decode(InputStream input) { Map<DecodeHintType, Object> hint = new HashMap<DecodeHintType, Object>(); hint.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE); String result = ""; try { BufferedImage img = ImageIO.read(input); int[] pixels = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); LuminanceSource source = new RGBLuminanceSource(img.getWidth(), img.getHeight(), pixels); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); Result r = reader.decode(bitmap, hint); result = r.getText(); } catch (Exception e) { result = "读取错误"; } return result; } public static void main(String[] args) { String imgname = String.valueOf(System.currentTimeMillis()) + ".png"; CodeModel info = new CodeModel(); info.setContents("客户:倍特 品牌:倍特 型号:XH001 日期:2018-06-19 检验员:易工"); info.setWidth(68); info.setHeight(68); info.setFontSize(12); info.setLogoFile(new File("F:\\软件安全下载目录\\personnelManage\\" + imgname)); info.setDesc("玫瑰之约"); info.setDate("2018-06-19"); info.setLogoFile(null); QR_Code code = new QR_Code(); } } 2.二维码实体类 public class CodeModel { /** * @return the date */ public String getDate() { return date; } /** * @param date * the date to set */ public void setDate(String date) { this.date = date; } /** * @return the contents */ public String getContents() { return contents; } /** * @param contents * the contents to set */ public void setContents(String contents) { this.contents = contents; } /** * @return the width */ public int getWidth() { return width; } /** * @param width * the width to set */ public void setWidth(int width) { this.width = width; } /** * @return the height */ public int getHeight() { return height; } /** * @param height * the height to set */ public void setHeight(int height) { this.height = height; } /** * @return the format */ public String getFormat() { return format; } /** * @param format * the format to set */ public void setFormat(String format) { this.format = format; } /** * @return the character_set */ public String getCharacter_set() { return character_set; } /** * @param character_set * the character_set to set */ public void setCharacter_set(String character_set) { this.character_set = character_set; } /** * @return the fontSize */ public int getFontSize() { return fontSize; } /** * @param fontSize * the fontSize to set */ public void setFontSize(int fontSize) { this.fontSize = fontSize; } /** * @return the logoFile */ public File getLogoFile() { return logoFile; } /** * @param logoFile * the logoFile to set */ public void setLogoFile(File logoFile) { this.logoFile = logoFile; } /** * @return the logoRatio */ public float getLogoRatio() { return logoRatio; } /** * @param logoRatio * the logoRatio to set */ public void setLogoRatio(float logoRatio) { this.logoRatio = logoRatio; } /** * @return the desc */ public String getDesc() { return desc; } /** * @param desc * the desc to set */ public void setDesc(String desc) { this.desc = desc; } /** * @return the whiteWidth */ public int getWhiteWidth() { return whiteWidth; } /** * @param whiteWidth * the whiteWidth to set */ public void setWhiteWidth(int whiteWidth) { this.whiteWidth = whiteWidth; } /** * @return the bottomStart */ public int[] getBottomStart() { return bottomStart; } /** * @param bottomStart * the bottomStart to set */ public void setBottomStart(int[] bottomStart) { this.bottomStart = bottomStart; } /** * @return the bottomEnd */ public int[] getBottomEnd() { return bottomEnd; } /** * @param bottomEnd * the bottomEnd to set */ public void setBottomEnd(int[] bottomEnd) { this.bottomEnd = bottomEnd; } /** * 正文 */ private String contents; /** * 二维码宽度 */ private int width = 400; /** * 二维码高度 */ private int height = 400; /** * 图片格式 */ private String format = "png"; /** * 编码方式 */ private String character_set = "utf-8"; /** * 字体大小 */ private int fontSize = 12; /** * logo */ private File logoFile; /** * logo所占二维码比例 */ private float logoRatio = 0.20f; /** * 二维码下文字 */ private String desc; /** * 下方日期 */ private String date; private int whiteWidth;//白边的宽度 private int[] bottomStart;//二维码最下边的开始坐标 private int[] bottomEnd;//二维码最下边的结束坐标 } 3.action中调用 @ResponseBody @RequestMapping(value = "/addqrcode") public String addqrcode(HttpServletRequest request, String msg) throws Exception { String realPath = request.getSession().getServletContext().getRealPath("/") + "\\qrcode\\"; msg = String.valueOf(System.currentTimeMillis()) + ".png"; CodeModel info = new CodeModel(); info.setContents("客户:" + request.getParameter("customer") + " 品牌:" + request.getParameter("brand") + " 型号:" + request.getParameter("model") + " 日期:" + request.getParameter("addtime") + " 检验员:" + request.getParameter("testpersion")); info.setWidth(68); info.setHeight(68); info.setFontSize(12); info.setLogoFile(new File(realPath + msg)); info.setDesc(request.getParameter("brand")); info.setDate(request.getParameter("addtime")); info.setLogoFile(null); QR_Code code = new QR_Code(); code.createCodeImage(info, realPath + msg); return msg; } 以上方法就可以实现带logo,以及下方显示文字的二维码。不需要logo,参数可以传null。 接来下说说二维码的打印,根据实际需要可以自定义设置二维码的尺寸,以及图片的格式 4.打印方法 需要注意的是:一是生成保存二维码的地址,二是打印机驱动必须启动 /** * 打印二维码 * * @param fileName * @param count */ @ResponseBody @RequestMapping(value = "/printImage") public static void printImage(String fileName, int count, HttpServletRequest request) { String realPath = request.getSession().getServletContext().getRealPath("/") + "\\qrcode\\"; try { DocFlavor dof = null; if (fileName.endsWith(".gif")) { dof = DocFlavor.INPUT_STREAM.GIF; } else if (fileName.endsWith(".jpg")) { dof = DocFlavor.INPUT_STREAM.JPEG; } else if (fileName.endsWith(".png")) { dof = DocFlavor.INPUT_STREAM.PNG; } // 获取默认打印机 PrintService ps = PrintServiceLookup.lookupDefaultPrintService(); PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); // pras.add(OrientationRequested.PORTRAIT); // pras.add(PrintQuality.HIGH); pras.add(new Copies(count)); pras.add(MediaSizeName.ISO_A10); // 设置打印的纸张 DocAttributeSet das = new HashDocAttributeSet(); das.add(new MediaPrintableArea(0, 0, 1, 1, MediaPrintableArea.INCH)); FileInputStream fin = new FileInputStream(realPath + fileName); Doc doc = new SimpleDoc(fin, dof, das); DocPrintJob job = ps.createPrintJob(); job.print(doc, pras); fin.close(); } catch (IOException ie) { ie.printStackTrace(); } catch (PrintException pe) { pe.printStackTrace(); } } 看着是不是很简单,完美的解决。 到这里已经完成了对文件的预览功能,如有需要可以加我Q群【308742428】大家一起讨论技术。 后面会不定时为大家更新文章,敬请期待。 喜欢的朋友可以关注下,粉丝也缺。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册