• [其他] java锁的详解
    锁的种类Java中的锁是一种同步机制,用于保护共享资源,防止多个线程同时访问。在Java中,锁可以分为不同的类型,每种类型都有其特定的优缺点和适用场景。重量级锁(Heavy Lock):重量级锁是一种互斥锁,它提供了最高的线程安全性。当一个线程获得了重量级锁时,其他线程必须等待该线程释放锁才能获得锁。因此,重量级锁的开销较大,可能会导致线程阻塞和性能下降。但是,由于重量级锁提供了最高的线程安全性,所以在需要确保数据完整性和一致性的情况下,重量级锁是非常有用的。轻量级锁(Lightweight Lock):轻量级锁是一种比重量级锁更轻量级的同步机制。它使用CAS操作来实现互斥访问,并且可以在没有竞争的情况下快速获取锁。因此,轻量级锁的开销较小,可以提高并发性能。但是,由于轻量级锁不是互斥的,所以如果多个线程同时尝试获取锁,则可能导致数据不一致的问题。互斥锁(Mutex Lock):互斥锁是一种基本的同步机制,它用于保护共享资源,防止多个线程同时访问。互斥锁提供了原子性操作,即在任何时候只能有一个线程访问共享资源。Java中的synchronized关键字就是一种互斥锁。读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。读写锁可以提高并发性能,特别是在读操作比写操作频繁的情况下。Java中的ReentrantReadWriteLock就是一种读写锁。可重入锁(Reentrant Lock):可重入锁允许同一个线程多次获取同一个锁,这意味着线程可以在执行完同步代码后再次获取该锁而不需要重新竞争。可重入锁通常用于递归调用等情况。Java中的ReentrantLock就是一种可重入锁。自旋锁(Spin Lock):自旋锁是一种基于忙等待的同步机制,它在获取锁时会一直循环等待,直到获取到锁为止。自旋锁的开销较大,因为它会占用大量的CPU时间。但是,自旋锁可以提供极高的并发性能,特别是在竞争激烈的情况下。乐观锁(Optimistic Lock):乐观锁是一种不涉及实际锁定的同步机制,它通过版本号或哈希值来检查共享资源是否被其他线程修改过。如果没有修改,则可以更新共享资源。乐观锁可以提高并发性能,但可能会导致数据不一致的问题。Java中的CAS操作就是一种乐观锁实现方式。悲观锁(Pessimistic Lock):悲观锁是一种实际锁定的同步机制,它在访问共享资源之前先将其锁定。悲观锁可以保证数据的一致性,但会导致并发性能下降。Java中的synchronized关键字就是一种悲观锁实现方式。以下是Java中各种锁的实现代码示例:1. synchronized关键字实现互斥锁[悲观锁]: public class SynchronizedDemo { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } 2. ReentrantLock类实现可重入锁: import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockDemo { private final ReentrantLock lock = new ReentrantLock(); public void doSomething() { lock.lock(); // 可重入锁必须先获取到锁才能执行同步代码,因此需要使用lock()方法获取锁 try { // 同步代码块 } finally { lock.unlock(); // 在finally块中释放锁,即使发生异常也需要释放锁 } } } 3. ReadWriteLock类实现读写锁: import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockDemo { private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public void readData() { rwl.readLock().lock(); // 只允许读取操作获取到读锁,因此需要使用readLock()方法获取读锁 try { // 读取共享资源的操作 } finally { rwl.readLock().unlock(); // 在finally块中释放读锁,即使发生异常也需要释放读锁 } } public void writeData() { rwl.writeLock().lock(); // 只允许写入操作获取到写锁,因此需要使用writeLock()方法获取写锁 try { // 写入共享资源的操作 } finally { rwl.writeLock().unlock(); // 在finally块中释放写锁,即使发生异常也需要释放写锁 } } } 4.自旋锁示例代码,它使用Java中的ReentrantLock类实现:import java.util.concurrent.locks.ReentrantLock; public class SpinLockDemo { private final ReentrantLock lock = new ReentrantLock(); public void doSomething() { while (true) { try { lock.lockInterruptibly(); // 尝试获取锁,如果获取失败则进入循环等待 break; } catch (InterruptedException e) { Thread.currentThread().interrupt(); // 抛出异常时中断当前线程 } } try { // 同步代码块 } finally { lock.unlock(); // 在finally块中释放锁,即使发生异常也需要释放锁 } } } 在上面的示例代码中,doSomething()方法会一直循环等待获取锁。当它尝试获取锁时,如果获取失败,则会抛出InterruptedException异常并中断当前线程。一旦它成功获取到锁,就可以执行同步代码块了。最后,无论同步代码块是否正常执行,doSomething()方法都会在finally块中释放锁。这样可以确保即使发生异常,也不会导致锁没有被正确释放的问题。5. 乐观锁示例代码,它使用Java中的CAS操作实现:import java.util.concurrent.atomic.AtomicInteger; public class OptimisticLockDemo { private final AtomicInteger count = new AtomicInteger(0); public void increment() { int currentCount = count.get(); while (true) { int nextCount = currentCount + 1; if (count.compareAndSet(currentCount, nextCount)) { break; } else { currentCount = nextCount; } } } } 在上面的示例代码中,increment()方法会不断尝试将共享资源的计数器从当前值加1。如果成功更新了计数器的值,则说明没有其他线程在同一时间点对共享资源进行了修改,因此可以安全地进行同步操作。否则,increment()方法会继续循环等待,直到获取到锁为止。这样可以确保即使发生竞争条件,也不会导致数据的不一致性问题。
  • [技术干货] 免费漂亮的Java图形验证码
    前言Java 图形验证码,支持自定义图片、中文、算术等类型,可用于 Java Web、JavaSE 等项目。真香!截图展示项目集成package com.kyger;import jakarta.servlet.ServletException;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Map;public class demo extends HttpServlet { private static final long serialVersionUID = 1L; public demo() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 编码 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");; response.setContentType("text/html; charset=utf-8"); // 后台处理 if (request.getMethod().equals("POST")){ String html, appId, appSecret; // 设置 AppId 及 AppSecret,在应用管理中获取 appId = "xxx"; appSecret = "xxx"; KgCaptchaSDK KgRequest = new KgCaptchaSDK(appId, appSecret); // 前端验证成功后颁发的 token,有效期为两分钟 KgRequest.token = request.getParameter("kgCaptchaToken"); // System.out.print(KgRequest.token); // 填写应用服务域名,在应用管理中获取 KgRequest.appCdn = "xxx"; // 请求超时时间,秒 KgRequest.connectTimeout = 5; // 用户登录或尝试帐号,当安全策略中的防控等级为3时必须填写,一般情况下可以忽略 // 可以填写用户输入的登录帐号(如:request.getParameter("username"),可拦截同一帐号多次尝试等行为 KgRequest.userId = "kgCaptchaDemo"; // request 对象,当安全策略中的防控等级为3时必须填写,一般情况下可以忽略 KgRequest.request = request; // java 环境中无法提供 request 对象,请分别定义:clientIp|clientBrowser|domain 参数,即: // KgRequest.clientIp = "127.0.0.1"; // 填写客户端IP // KgRequest.clientBrowser = ""; // 客户端浏览器信息 // KgRequest.domain = "http://localhost"; // 你的授权域名或服务IP // 发送验证请求 Map<String, String> requestResult = KgRequest.sendRequest(); if("0".toString().equals(requestResult.get("code"))) { // 验签成功逻辑处理 *** // 这里做验证通过后的数据处理 // 如登录/注册场景,这里通常查询数据库、校验密码、进行登录或注册等动作处理 // 如短信场景,这里可以开始向用户发送短信等动作处理 // ... html = "<script>alert('验证通过');history.back();</script>"; } else { // 验签失败逻辑处理 html = "<script>alert(\"" + requestResult.get("msg") + " - " + requestResult.get("code") + "\");history.back();</script>"; } response.getWriter().append(html); } else { response.sendRedirect("index.html"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
  • [技术干货] Java中的锁
     在Java中,锁是同步代码块或方法的重要机制之一。当多个线程需要访问共享资源时,锁可以确保这些线程能够安全地访问该资源,避免出现数据竞争和线程安全问题。  Java中的锁分为两种类型:内置锁和显式锁。  内置锁 内置锁也称为监视器锁,它是Java中隐式提供的一种锁。每个对象都有一个相关联的内置锁,可以通过synchronized关键字来获取这个锁。  使用synchronized关键字 synchronized关键字可以用于同步代码块或方法。下面是一个同步代码块的例子:  java public class SyncExample {     private Object lock = new Object();      public void syncMethod() {         synchronized(lock) {             // 同步代码块         }     } } 在上面的例子中,同步代码块使用了lock对象作为内置锁。在执行同步代码块期间,其他试图获取lock对象的线程将被阻塞,直到锁被释放。  synchronized关键字还可以用于同步方法。下面是一个同步方法的例子:  java public class SyncExample {     private Object lock = new Object();      public synchronized void syncMethod() {         // 同步方法体     } } 在上面的例子中,syncMethod()方法将使用SyncExample对象的内置锁进行同步。在执行该方法期间,其他试图访问syncMethod()方法的线程将被阻塞,直到锁被释放。  隐式锁 除synchronized关键字外,Java还提供了一些基于内置锁的类和接口,例如ReentrantLock、ReentrantReadWriteLock和Condition等。这些类和接口提供了更灵活的锁定机制,允许获取和释放锁以及进行条件变量的操作。  显式锁 与内置锁不同,显式锁需要手动获取和释放锁。Java提供了java.util.concurrent.locks.Lock接口来定义这种类型的锁,并提供了一些实现类,例如ReentrantLock和ReentrantReadWriteLock.ReadLock等。  使用Lock接口 下面是一个使用ReentrantLock实现锁的例子:  java public class LockExample {     private Lock lock = new ReentrantLock();      public void lockMethod() {         lock.lock();         try {             // 上锁后要执行的代码块         } finally {             lock.unlock();         }     } } 在上面的例子中,lock()方法将获取锁,unlock()方法将释放锁。与synchronized关键字不同,显式锁可以通过调用tryLock()方法来尝试获取锁而不会阻塞线程。此外,Lock接口还提供了一些其他的便利方法,例如lockInterruptibly()和newCondition()等。  总结 Java中的锁是控制多线程访问共享资源的重要机制。内置锁使用synchronized关键字实现,显式锁使用Lock接口和相关类实现。 
  • [问题求助] 对接华为aicc,座席二次开发的时间大概需要多久。
    【问题来源】    汉口银行    【问题简要】    座席二次开发问题【问题类别】    CC-Gateway【AICC解决方案版本】    AICC版本:AICC 22.200    UAP版本:UAP9600 V100R005C00SPC113对接华为aicc,座席二次开发的时间大概需要多久。    CTI版本:  ICD V300R008C25spc012【期望解决时间】    尽快【问题现象描述】对接华为aicc,座席二次开发的周期时长,大概需要多少人天。
  • [其他] Java中限制并发数的方法
    Java中限制并发数的方法有以下几种:使用synchronized关键字:synchronized可以用于方法或代码块上,它可以保证同一时间只有一个线程执行该代码块或方法。通过在需要控制并发的地方加上synchronized关键字,可以有效地控制并发数。【并发数限制为1】使用ReentrantLock类:ReentrantLock是Java提供的一个可重入的互斥锁,它可以用来实现同步和锁定操作。通过ReentrantLock类可以更加灵活地控制并发数。与synchronized关键字相比,ReentrantLock提供了更加灵活的控制方式,例如可以指定公平锁或非公平锁、超时时间等。使用ReentrantLock需要先创建一个ReentrantLock对象,然后调用lock()方法获取互斥锁,执行完相关操作后调用unlock()方法释放互斥锁。在获取互斥锁时,可以通过tryLock()方法尝试获取锁,如果获取成功则返回true,否则返回false。此外,ReentrantLock还提供了Condition接口,可以实现等待/通知机制。使用Semaphore类:Semaphore是Java提供的一个计数信号量,它可以用来限制同时访问某个资源的线程数量。通过Semaphore类可以实现对并发数的限制。Semaphore是Java提供的一个计数信号量,它可以用来限制同时访问某个资源的线程数量。Semaphore有两个重要方法:acquire()和release()。1>acquire()方法:如果当前线程获取到信号量,则返回true;否则,阻塞等待直到有其他线程释放信号量。2>release()方法:增加信号量的计数器并立即返回。如果此时计数器的值大于指定的上限,则只有已经持有信号量的线程才能继续执行。使用ThreadPoolExecutor类:ThreadPoolExecutor是一个线程池管理类,它可以自动管理线程的创建和销毁,并且可以限制同时运行的线程数量。通过ThreadPoolExecutor类可以更加方便地控制并发数。使用ThreadPoolExecutor需要先创建一个ThreadPoolExecutor对象,然后通过submit()方法提交任务,ThreadPoolExecutor会自动将任务分配给空闲的线程执行。可以通过setCorePoolSize()、setMaxPoolSize()、setKeepAliveTime()等方法来配置线程池的相关参数。
  • [技术干货] JAVA5种字符串拼接
    1.+号拼接2.concat 拼接3.join拼接4.StringBuffer拼接5.StringBuilder拼接public class test { public static void main(String[] args) { String add = add(); String concat = concat(); String join = join(); String buffer = buffer(); String builder = builder(); } public static String add() { String string = ""; long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { string += "a"; } long endTime = System.currentTimeMillis(); System.out.println("+号拼接耗时:" + (endTime - startTime)); return string; } public static String concat() { String string = ""; long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { string = string.concat("a"); } long endTime = System.currentTimeMillis(); System.out.println("concat拼接耗时:" + (endTime - startTime)); return string; } public static String join() { String string = ""; long startTime = System.currentTimeMillis(); List<String> list = new ArrayList<String>(); for (int i = 0; i < 1000000; i++) { list.add("a"); } string = String.join(string, list); long endTime = System.currentTimeMillis(); System.out.println("join拼接耗时:" + (endTime - startTime)); return string; } public static String buffer() { StringBuffer sb = new StringBuffer(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { sb.append("a"); } long endTime = System.currentTimeMillis(); System.out.println("StringBuffer拼接耗时:" + (endTime - startTime)); return sb.toString(); } public static String builder() { StringBuilder sb = new StringBuilder(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { sb.append("a"); } long endTime = System.currentTimeMillis(); System.out.println("StringBuilder拼接耗时:" + (endTime - startTime)); return sb.toString(); }} 执行效率+号拼接耗时:6501concat拼接耗时:1739join拼接耗时:13StringBuffer拼接耗时:2     (线程安全,多线程推荐)StringBuilder拼接耗时:1    (线程不安全)
  • [问题求助] 坐席二次开发问题
    【问题来源】    汉口银行    【问题简要】    座席二次开发问题【问题类别】    CC-Gateway【AICC解决方案版本】    AICC版本:AICC 22.200    UAP版本:UAP9600 V100R005C00SPC113    CTI版本:  ICD V300R008C25spc012【期望解决时间】    尽快【问题现象描述】您好,二次开发CCGateway接续接口需要使用轮询接口做会话保活。这个是在坐席前端轮询调用接口:https://ip:port/agentgateway/resource/agentevent/{agentid}?calldata=XXX做会话保持吗?
  • [问题求助] 座席二次开发问题
    【问题来源】    汉口银行【问题简要】    座席二次开发问题【问题类别】    CC-Gateway【AICC解决方案版本】    AICC版本:AICC 22.200    UAP版本:UAP9600 V100R005C00SPC113    CTI版本:  ICD V300R008C25spc012【期望解决时间】    尽快【问题现象描述】 1. 对接华为AICC,异常处理机制是怎样的。比如座席端签入后,浏览器崩了,能重新签入吗? 2. 用户侧,发起呼叫成功,如果中途异常掉线了,后面处理逻辑是怎样的,能重新建立连接吗?
  • [交流吐槽] 求助下,idea全家桶太重了怎么办、
    现在是idea+datagrip+webstorm。 启动项目直接内存拉满 ,
  • [热门活动] 速进,四月份干货合集它来了!!!
     大家好本月为大家带来codeArts技术干货合集。 1.Pandas提取含有指定字符串的行(完全匹配,部分匹配)【转】 https://bbs.huaweicloud.com/forum/thread-0232118247508457054-1-1.html  2.一文带你吃透Python中的日期时间模块【转】 https://bbs.huaweicloud.com/forum/thread-0287118247600909060-1-1.html  3.Linux 安装conda的踩坑日记 https://bbs.huaweicloud.com/forum/thread-02104118248070541037-1-1.html  4.Oracle JDK 和 OpenJDK有什么区别? https://bbs.huaweicloud.com/forum/thread-0214117797316272025-1-1.html  5.JAVA如何实现文件的压缩和解压 https://bbs.huaweicloud.com/forum/thread-0287117797383963030-1-1.html  6.搞清楚TensorFlow2--Keras的Tokenizer https://bbs.huaweicloud.com/forum/thread-0201117864382443016-1-1.html  7.Python德劳内三角剖分详解【转】 https://bbs.huaweicloud.com/forum/thread-0201118245888101041-1-1.html  8.python http通信接口开发示例【转】 https://bbs.huaweicloud.com/forum/thread-0214118246273043053-1-1.html  9.基于Python制作简单的井字棋游戏【转】 https://bbs.huaweicloud.com/forum/thread-0258118246382450049-1-1.html  10.Python中re.findAll()、re.sub()、set()的使用【转】 https://bbs.huaweicloud.com/forum/thread-0287118246466069057-1-1.html  11.Python开发常用五种循环方式的场景性能比较【转】 https://bbs.huaweicloud.com/forum/thread-02104118246598051036-1-1.html  12.Python利用PsUtil实现实时监控系统状态【转】 https://bbs.huaweicloud.com/forum/thread-0214118246712044054-1-1.html  13.Python 程序通过可执行文件部署方式【转】 https://bbs.huaweicloud.com/forum/thread-0287118246833763058-1-1.html  14.Python网络爬虫之获取网络数据【转】 https://bbs.huaweicloud.com/forum/thread-0232118246915486053-1-1.html  15.VBS字符串编码转换函数代码【转】 https://bbs.huaweicloud.com/forum/thread-0214118246992498055-1-1.html  16.批处理echo、echo off、echo on、@、@echo off【转】 https://bbs.huaweicloud.com/forum/thread-0201118247149056042-1-1.html  17.Python嵌套循环的使用【转】 https://bbs.huaweicloud.com/forum/thread-0287118247410572059-1-1.html  18.使用@Autowired为什么会被 IDEA 警告? https://bbs.huaweicloud.com/forum/thread-0287117797109592029-1-1.html  19.剖析JAVA中Stream流的实现原理 https://bbs.huaweicloud.com/forum/thread-0214117797168254024-1-1.html  20.SpringBoot 整合 ElasticSearch 进行各种高级查询 https://bbs.huaweicloud.com/forum/thread-0258117797246098029-1-1.html 
  • [技术干货] 使用Idea 进行合并代码分支(例如:从dev合并到test)
    简介Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 [1] 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。Git 是基于 Linux内核开发的版本控制工具。与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持(wingeddevil注:这得分是用什么样的服务端,使用http协议或者git协议等不太一样。并且在push和pull的时候和服务器端还是有交互的。),使源代码的发布和交流极其方便。 Git 的速度很快,这对于诸如 Linux kernel 这样的大项目来说自然很重要。 Git 最为出色的是它的合并跟踪(merge tracing)能力。 实际上内核开发团队决定开始开发和使用 Git 来作为内核开发的版本控制系统的时候,世界开源社群的反对声音不少,最大的理由是 Git 太艰涩难懂,从 Git 的内部工作机制来说,的确是这样。但是随着开发的深入,Git 的正常使用都由一些友好的脚本命令来执行,使 Git 变得非常好用,即使是用来管理我们自己的开发项目,Git 都是一个友好,有力的工具。现在,越来越多的著名项目采用 Git 来管理项目开发。 一、整体合并 团队协作中,开发人员A、B、C分别在dev上进行功能开发,并push代码到远端dev上。当测试人员需要对功能进行测试的时候,我们需要把dev上新增的功能代码合并到test分支上去。  步骤: 1、将dev上的代码push到远端dev上。 2、切换分支到test分支。(就是切换到将要合并的目标分支) 3、拉取代码,确保test分支为远端最新的代码。4、合并分支 5、有冲突,先解决冲突后再合并,没有冲突则合并成功。  6、push代码到远端test分支上去。  二、针对某次提交的合并  团队协作中,开发人员较多,采用上面统一合并分支的形式,如果出现冲突,需要询问对应的开发人员进行代码的取舍,有代码丢失和错乱的风险,所以我们在项目开发中会采用遴选合并分支的方式。(自己写的代码,自己合并到对应的目标分支上去)  步骤:  1、在dev分支上,查看提交历史。 2、复制某次提交的版本号。3、切换到test分支(注意:切换成功后,最好pull拉取下代码,再执行下图命令),按下图执行命令。4、大功告成!———————————————— 原文链接:https://blog.csdn.net/wucaiyun225/article/details/122844223 
  • [技术干货] 解决错误com/fasterxml/jackson/core/StreamWriteFeature nested exception is java.lang.NoClassDefFoundError
    这个错误可能会有很多方面造成的,我就讲下我碰到的几个出错的方面吧 简介Spring是分层的 Java SE/EE应用full- stack轻量级开源框架,以IoC(Inversion of Control:反转控制)和AOP( Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC和持久层 Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE企业应用开源框架。 Jackson 是用来序列化和反序列化 json 的 Java 的开源框架。Spring MVC 的默认 json 解析器便是 Jackson。与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。 Jackson 的 1.x 版本的包名是 org.codehaus.jackson ,当升级到 2.x 版本时,包名变为 com.fasterxml.jackson,本文讨论的内容是基于最新的 Jackson 的 2.9.1 版本。 Jackson 的核心模块由三部分组成。 jackson-core,核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。 jackson-annotations,注解包,提供标准注解功能; jackson-databind ,数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。 1.版本不兼容 spring的版本和jackson的版本不兼容导致的,这个也是我出错的原因,jackson版本2.8.9好像需要spring4.3版本以上,这个我不确定,我的spring版本4.2就出问题了 2.jackson包冲突导致的 如何查看maven的包冲突呢,可以·使用快捷键Ctrl+Shift+Alt+U,或者是打开pom.xml,右键选择maven,然后选择 Show Dependencies 进入依赖包结构之后,可以用走上方的加减图标进行放大和缩小红线的就是有冲突的包,可以选择右键—》exclude把冲突的包排除掉排除冲突的包之后回到pom.xml进行刷新之后冲突的包就被排除了3.没有加入相应的依赖需要加入的jackson依赖有三种,分别为<!-- jackson -->     <dependency>       <groupId>com.fasterxml.jackson.core</groupId>       <artifactId>jackson-databind</artifactId>       <version>${jackson.verson}</version>     </dependency>     <dependency>       <groupId>com.fasterxml.jackson.core</groupId>       <artifactId>jackson-core</artifactId>       <version>${jackson.verson}</version>     </dependency>     <dependency>       <groupId>com.fasterxml.jackson.core</groupId>       <artifactId>jackson-annotations</artifactId>       <version>${jackson.verson}</version>     </dependency> 以上是我目前知道的可能导致错误的三个方面,如果有其他方面会导致这些问题,欢迎留言。原文链接:https://blog.csdn.net/Mustang_carrot/article/details/108364614
  • [技术干货] java 使用File 创建文件和文件夹
    概述: 封装一个磁盘路径字符串,对这个路径可以执行一次操作 可以封装文件路径、文件夹路径、不存在的路径 创建对象 File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新的File实例 new File(“d:/abc/a.txt”); new File(“d:/abc”,”a.txt”);  常用方法 创建: createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false。 mkdir() 在指定位置创建一个单级文件夹。 mkdirs() 在指定位置创建一个多级文件夹。 renameTo(File dest)如果目标文件与源文件是在同一个路径下,那么renameTo的作用是重命名, 如果目标文件与源文件不是在同一个路径下,那么renameTo的作用就是剪切,而且还不能操作文件夹。  删除: delete() 删除文件或者一个空文件夹,不能删除非空文件夹,马上删除文件,返回一个布尔值。 deleteOnExit()jvm退出时删除文件或者文件夹,用于删除临时文件,无返回值。  判断: exists() 文件或文件夹是否存在。 isFile() 是否是一个文件,如果不存在,则始终为false。 isDirectory() 是否是一个目录,如果不存在,则始终为false。 isHidden() 是否是一个隐藏的文件或是否是隐藏的目录。 isAbsolute() 测试此抽象路径名是否为绝对路径名。  获取: getName() 获取文件或文件夹的名称,不包含上级路径。 getAbsolutePath()获取文件的绝对路径,与文件是否存在没关系 length() 获取文件的大小(字节数),如果文件不存在则返回0L,如果是文件夹也返回0L。 getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。 lastModified()获取最后一次被修改的时间。  文件夹相关: static File[] listRoots()列出所有的根目录(Window中就是所有系统的盘符) list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。 listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操作会返回null。 list(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。 listFiles(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。  /*常用方法测试*/ public class TestFile {     public static void main(String[] args) throws IOException {         //1.创建File类对象         /*1.ready目录与1.txt需要自己手动创建         * 2.File需要导包:import java.io.File;         * 3.路径是String类型,必须写正确,不然找不到文件         * 4.完整的文件名包含两部分:文件名+后缀名*/         File file = new File("E:\\ready\\1.txt");          //2.1测试File中的常用方法         System.out.println(file.length());//3,获取文件的字节量         System.out.println(file.exists());//true,判断文件是否存在         System.out.println(file.isFile());//true,判断是否为文件         System.out.println(file.isDirectory());//false,判断是否为文件夹         System.out.println(file.getName());//1.txt获取文件名         System.out.println(file.getParent());//E:\ready 获取父级路径         System.out.println(file.getAbsolutePath());//E:\ready\1.txt 获取带盘符的完整路径:绝对路径          //2.2 测试创建与删除         /*new 只会帮你在内存中创建一个File类型的对象         * 并不会帮你在磁盘中创建一个真实存在的2.txt文件*/         file = new File("E:\\ready\\2.txt");          //创建一个之前不存在的文件2.txt,如果创建成功,会返回true         /*如果指定创建文件的路径不对,会抛出异常:java.io.Exception         * 所以需要提前处理这个问题,我们暂时选择在main()上抛出         * 这个IO异常是目前我们遇到的强制要求必须预先处理的异常         * 如果不处理,方法的调用会报错,通不过编译*/         System.out.println(file.createNewFile());//创建之前不存在的文件          file = new File("E:\\ready\\m");         System.out.println(file.mkdir());//创建之前不存在的单层文件夹          file = new File("E:\\ready\\a\\b\\c");         System.out.println(file.mkdirs());//创建之前不存在的多层文件夹          System.out.println(file.delete());//c被删除,删除空文件夹或者文件          file = new File("E:\\ready\\a");         System.out.println(file.delete());//false,a文件夹不是空的,里面有内容          file = new File("E:\\ready\\2.txt");         System.out.println(file.delete());//2.txt被删除,可以删除文件          //2.3测试展示文件列表         file = new File("E:\\ready");         String[] list = file.list();/*不常用*/         System.out.println(Arrays.toString(list));         //这句话会报错,因为这是一个String[],所以数组中每个元素都是String类型的         //那么只能用String类中的方法,而isDirectory()是File类中的方法         //System.out.println(list[0].isDirectory());          File[] fs = file.listFiles();/*常用*/         System.out.println(Arrays.toString(fs));         System.out.println(fs[0].isDirectory());     } } 原文链接:https://blog.csdn.net/ldqchat/article/details/123735361
  • [技术干货] List截取的几种方式
    RT: 为了方便先创建一个类的静态属性,并赋值,业务要求,返回n条数据,不足n条全部返回 public class SubList {     private static List<Dog> dogList;     static {         Dog dog1 = Dog.builder().age(8).build();         Dog dog2 = Dog.builder().age(2).build();         Dog dog3 = Dog.builder().age(9).build();         Dog dog4 = Dog.builder().age(9).build();         Dog dog5 = Dog.builder().age(1).build();         Dog dog6 = Dog.builder().age(18).build();         Dog dog7 = Dog.builder().age(10).build();         dogList = Lists.newArrayList(dog1,dog2,dog3);         }         ....     } 1、List原生的sub方法   /**      * 原生的      */     @Test     public void test1(){         List<Dog> dogs = dogList.subList(0, 2);         System.out.println(dogs);     } 1、1源码(可自行DEBUG,ArrayList举例),由下面源码可知道,会先调用subListRangeCheck(…),进行越界检查,因为ArayList底层是数组,数组是有越界问题的,针对不同情况,源码会抛出几个异常,所以我们在使用该方法的时候也要做判断,不足几条就要全部返回 缺点:1、会出现越界问题 需要手动校验 2、会出现空指针异常 需要手动校验      public List<E> subList(int fromIndex, int toIndex) {         subListRangeCheck(fromIndex, toIndex, size);         return new SubList(this, 0, fromIndex, toIndex);     }      static void subListRangeCheck(int fromIndex, int toIndex, int size) {         if (fromIndex < 0)             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);         if (toIndex > size)             throw new IndexOutOfBoundsException("toIndex = " + toIndex);         if (fromIndex > toIndex)             throw new IllegalArgumentException("fromIndex(" + fromIndex +                                                ") > toIndex(" + toIndex + ")");     } 2、可以使用stream流的方式,JDK8特性,优点,不足的话会全部返回  List<Dog> collect = dogList.stream().limit(10).collect(Collectors.toList()); 3、可以使用一些第三方库,比如hutoo里面的CollectionUtil  //(1)、可以解决空指针问题         dogList = null;         List<Dog> sub = CollectionUtil.sub(dogList, 0, 5);         System.out.println(sub); //null //(2)、可以解决越界问题   我一般开发就用这个工具类比较多 ———————————————— 原文链接:https://blog.csdn.net/weixin_42506330/article/details/107858615 
  • [技术干货] vue element-ui select 多选验证不通过问题处理
    问题描述 在使用element form表单提交时,会涉及到下拉框el-select的使用,根据具体需求可设置为单选或者多选,默认为单选。当需求变更时,需要从单选改成多选,只需在el-select 标签中添加multiple即可,同时更改绑定属性为数组,这时保存表单验证却不通过。 但是选中值后验证不消失,以为是vue没有监听到数据变化导致的,试过this.$set()方法重新设置属性值,但也是一样的无效。 原因分析: 折腾半天,发现由于表单验证规则没加type:array导致的 当我们使用单选时,添加的规则是这样的。其实这里默认省略了验证字段的类型字段 type:string rules: {     trainType: [          {            required: true,            message: "请输入..",            trigger: "blur,change",          }      ] } 没省略应该是这样的  rules: {     trainType: [          {            type: string,            required: true,            message: "请输入..",            trigger: "blur,change",          }      ] } 而改成多选后绑定的值为数组类型,在使用默认校验string的规则去校验数组,这就导致表单验证不通过,同时控制台也会有警告。 解决方案: 在对应验证字段验证规则中添加type:array,就可解决问题 rules: {     trainType: [          {            type: array,            required: true,            message: "请输入..",            trigger: "blur,change",          }      ] } 已经没有验证提示,问题解决。 ———————————————— 原文链接:https://blog.csdn.net/u012386455/article/details/124328552 
总条数:2294 到第
上滑加载中