今天在转化时间的时候出错了,系统首页需要以年,月,日三种分类进行日期统计,因为我平常一直使用LocalDateTime,没有使用过LocalTime和LocalDate,所以在今天我修改日期的时候使用DateTimeFormater格式化字符串将"2024-11-12"转换成LocalDateTime 的时候报错了
代码大致是:
123456@Testvoid testLocalDateTime() { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime parse = LocalDateTime.parse("2024-11-12", dateTimeFormatter); System.out.println(parse);}
错误信息
1java.time.format.DateTimeParseException: Text '2024 ...
缘由
今天在回归问题的时候发现一个bug,在统计表中数量的时候,有一个刷新按钮,可以获取最新的表中的数据数量,但是bug是在点击刷新的时候会一直处于刷新状态,思考过后,找出问题缘由
问题:在点击刷新按钮的时候,后台通过sql去查询指定数据源下的指定表的数量,在获取的时候后台接口可能由于数据库连接问题,导致接口一直没有返回结果,所以前台中表的数据展示按钮一直处于刷新状态,最后接口到达了前台设置的超时时间30s后,接口连接中断,然后导致一直处于刷新状态。
解决方法
设置接口超时时间,当时间超过指定时间之后,就返回出一个错误信息,让前台不要再等待了直接进行下一步操作就行
想要给每一个接口都设置超时时间,如果在每一个接口中判断等待一定时间的时候函数还是没有执行完毕,则返回出错误信息,有两种实现方式
异步线程加切面方式
将耗时操作使用线程来封装,指定线程的超时时间
使用 ExecutorService 结合 Future 来实现超时控制
通过Callable创建一个可返回的的结果,并且可能抛出异常的任务
利用ExecutorService.submit 方法来提交Callable到线程池中 ...
原因
今天在适配Milvus数据源的时候,代码出问题了,问题是
Milvus中的一个依赖包中包含protobuf这个包,这个包的版本是3.24.0。
同时还有一个依赖forest-spring-boot-starter也包含protobuf这个包,版本是3.14.0,
但是milvus中使用MilvusClient在创建client连接的时候会需要protobuf3.24.0中的GeneratedMessageV3的isStringEmpty这个方法
但是protobuf 3.14.0中的GeneratedMessageV3没有isStringEmpty方法
由于Milvus是外部包引入的,所以会导致冲突将3.24.0转换成3.14.0
配置文件如下,这是工程A引入的依赖
123456789101112131415161718<dependencies> <!-- 依赖于nuyoah-framework模块 --> <dependency> <groupId>org.example</groupId& ...
1.BIO,NIO,AIO分别是什么
BIO
同步阻塞式IO操作,使用BIO读取数据的时候线程会被阻塞住,并且需要线程主动的去查询是否有数据可读,并且需要处理完一个Socket之后才能处理下一个Socket
NIO
同步非阻塞IO,使用NIO读取数据的时候,线程不会阻塞,但是需要线程主动去查询是否有IO事件
AIO
异步非阻塞IO,使用AIO读取数据的时候线程不会阻塞,并且当有数据可读取的时候会通知线程,不需要线程主动去查询
2.零拷贝
零拷贝是指:应用程序在需要将内核中的一块区域中的内容转移到另外一个快内核中去,不需要经过先复制到用户空间,在转移到目标内核中区域中去,而直接实现转移,利用操作系统的transferTo()方法
**优点:**省略了两次内存交换的时间,直接实现内核中的转移
3.Netty是什么?和Tomcat有什么区别?特点是什么
Netty是一个基于NIO的异步网络通讯框架,性能高,封装了原生的NIO编码的复杂度,开发者可以直接使用Netty来开发高效率的各种网络服务器,并且编码简单。
Tomcat是一个web服务器,是一个Servlet容器,基本上To ...
最近在设置统一interceptor拦截请求校验请求参数的时候出现了一个问题,就是我需要在拦截器中获取请求头中所带的参数,包括GET参数和请求体中的参数。
问题:当在拦截器中拦截到请求体中的参数的时候对应的controller方法中的**@RequestBody注解失效**,
报错原因:没有传入所需参数
但是我在拦截器中确实获取到了请求头中包含的请求体参数,为什么会在Controller层中获取不到?
原因:当我在读取请求头中的请求体参数的时候,请求体是以流的形式存储,我获取到请求体的时候,请求体中的指针会指到最后一个位置,导致Controller层在通过请求头获取请求体参数的时候发现请求体中的指针后面没有东西,于是报错:没有传入请求体参数
解决方法:自己包装一个Request请求类实现ServletRequest类,重写getInputStream方法,并使用过滤器,在请求还没有到拦截器之前将请求体换成自己的封装的请求体类即可
自己封装的请求体
1234567891011121314151617181920212223242526272829303132333435363738394 ...
1. 线程池中提交一个任务的流程是怎样的
文字
在使用execute()方法提交一个Runnable对象时
会先判断当前线程池中的线程数是否小于corePoolSize
如果小于,则创建新线程并执行Runnable
如果大于等于,则尝试将Runnable加入到workQueue中
如果workQueue没满,则将Runnable正常入队,等待执行
如果workQueue满了,则会入队失败,那么会尝试继续增加线程
如果当前线程池中的线程数是否小于maximumPoolSize
如果小于,则创建新线程并执行任务
如果大于等于,则执行拒绝策略,拒绝次Runnable
流程图
代码
创建线程执行
12345678910@Testvoid testRunnable() { ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 200, TimeUnit.MINUTES, new LinkedBlockingDeque<>()); executor.execute(new Runn ...
今天在判断一个List中是否包含一个指定的元素的时候,发现可以有两种方式
使用for循环依次比较
使用自带的contains方式来判断
想着是contains的底层跟for循环依次比较有什么区别,如果都是依次比较的话,直接使用for循环是否更快一些(少一层封装)
查看ArrayList的contains的底层源码发现:底层确实是使用for循环来比较的
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970/** * Returns {@code true} if this list contains the specified element. * More formally, returns {@code true} if and only if this list contains * at least one ...
第一章:SpringSecurity入门
功能
身份认证(authentication)
身份认证是验证谁正在访问系统资源 ,判断用户是否为合法用户。认证用户的常见方式是要求用户输入用户名和密码。
授权(authorization)
用户进行身份认证后,系统会控制谁能访问哪些资源,这个过程叫做授权。用户无法访问没有权限的资源。
防御常见攻击(protection against common attacks)
CSRF
HTTP Headers
HTTP Requests
案例-身份认证
创建项目引入依赖
pom文件依赖
1234567891011121314151617181920212223242526272829303132333435<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3 ...
Function函数式编程
Function函数在java这个包中定义
java.util.function
消费者(consumer:接收参数不返回)
Consumer是一个函数式接口**@FunctionalInterface在接口上添加这个注解可以帮助扫描该接口是否是函数式接口===>只能有一个为实现的方法**
Consumer里面accept方法是唯一的为实现的方法
1void accept(T t);
接收参数但是不返回参数
123// 定义消费者Consumer<String> consumer = System.out::println;consumer.accept("Hello");
提供者(Supplier:不接收参数但是返回)
Supplier里面的Get方法就是提供者方法
12345678910@FunctionalInterfacepublic interface Supplier<T> { /** * Gets a result. * * @return a re ...