Java way to explore https:https://cdn.v2ex.com/navatar/03af/dbd6/63_normal.png?m=1644490200 https:https://cdn.v2ex.com/navatar/03af/dbd6/63_large.png?m=1644490200 2025-12-16T05:45:07Z Copyright © 2010-2018, V2EX 求助 泛型转换碰到一个很奇怪的问题 Object 放 Redis 自动变成 JSONObject 了 tag:www.v2ex.com,2025-12-16:/t/1179190 2025-12-16T03:32:41Z 2025-12-16T05:45:07Z heliotrope member/heliotrope public <T> void setCacheObject(final String key, final T value) { redisTemplate.opsForValue().set(key, value); } public <T> T getCacheObject(final String key) { ValueOperations<String, T> operation = redisTemplate.opsForValue(); return operation.get(key); }

这个逻辑在调用 getCacheObject 时 返回对象会随机变成 com.alibaba.fastjson.JSONObject 或者 com.alibaba.fastjson2.JSONObject 导致外部调用时报类型强制转换异常

就是 ruoyi 脚手架 里面的 RedisService TokenService 里面调用 getLoginUser 就会报 java.lang.ClassCastException: com.alibaba.fastjson2.JSONObject cannot be cast to com.ruoyi.system.api.model.LoginUser

而且之前都正常 一段时间没运行 再跑就出现这个问题 定义是在 RedisConfig

RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); 

全部都是 object 获取到就变 JSONObject 了 实在是没搞懂哪里有问题

]]>
Java Agent 该怎么快速学习?有教程文档推一下吗? tag:www.v2ex.com,2025-12-04:/t/1176980 2025-12-04T12:43:34Z 2025-12-14T11:51:24Z tiRolin member/tiRolin 我最近入职了一家新公司,我在里面主要是负责做 APM ,主要使用 Java Agent 去做,我去 B 站找了一些教程,但是都只是一些简单入门的内容,公司内部也有提供一些教程,但是目前我只看到了跟公司产品本身相关的内容,我想问问各位该怎么快速学习 Java Agent 呢?有没有什么教程推一下?给我关键字或者是文档链接就好,我会自己去看的,视频也可以,我都会去看的。

小弟我在这里先谢谢各位了

]]>
能不能别用那烦人的 MyBatis-Plus 了! tag:www.v2ex.com,2025-12-04:/t/1176946 2025-12-04T09:23:26Z 2025-12-03T17:23:26Z reavid member/reavid 刚刚 clone 公司的项目代码,看到一堆的 Wrapper 真的绷不住了。好好的在 xml 里面写 SQL 不好吗?非要在 Service 写那么多和业务无关的东西,代码看得我头大。

@Override public int deleteByColorId(Long colorId,String userCode) { LambdaUpdateWrapper<ColorLibraryFile> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.set(ColorLibraryFile::getDeletedFlag,DeletedFlagEnum.DELETE.getCode()); updateWrapper.set(ColorLibraryFile::getDeletedBy,userCode); updateWrapper.set(ColorLibraryFile::getDeletedTime, new Date()); updateWrapper.eq(ColorLibraryFile::getColorId,colorId); updateWrapper.eq(ColorLibraryFile::getDeletedFlag,DeletedFlagEnum.NORMAL.getCode()); return colorLibraryFileDao.update(null,updateWrapper); } 
]]>
作为 Java boy 你们业余时间会学点什么? tag:www.v2ex.com,2025-12-03:/t/1176527 2025-12-03T01:38:29Z 2025-12-04T14:24:33Z blababa member/blababa 各位 v 友们!有无无敌好用的剪辑软件求推荐! tag:www.v2ex.com,2025-11-13:/t/1172567 2025-11-13T07:52:43Z 2025-11-13T07:58:47Z xhf1024 member/xhf1024 最近马上要结婚了,亲友们的视频想自己拿来剪辑剪辑!玩一玩!

]]>
如何从反射的 Field/Method 动态构造 mybatis 的 SFunction? tag:www.v2ex.com,2025-11-13:/t/1172483 2025-11-13T03:20:42Z 2025-11-13T03:19:42Z a33291 member/a33291 Java 得冗余与啰嗦是不是对 AI 不友好 tag:www.v2ex.com,2025-11-13:/t/1172476 2025-11-13T03:02:55Z 2025-11-13T09:39:50Z 2018yuli member/2018yuli 可能是 Java 得项目都比较大,感觉现在其他语言得小项目 AI 能接近 100% 的完成。但是打开一个 Java 的 cloud 项目,看到那无数并列的 controller. AI 都能扫到 token 耗尽。然后,实际上,他真的有很多功能么?很多业务么?

我在想,为了 AI 阅读方便,我们是不是应该将所有 crud 都纳到框架层,或者是放到独立的包。业务层只有存逻辑。提升信息密度。这样才对 AI 友好,各位觉得呢,Java 是不是需要这样子的框架。

我个人最近好久没做 Java 了,不喜轻喷。

]]>
问一个日志不打印栈信息的问题 tag:www.v2ex.com,2025-11-07:/t/1171249 2025-11-07T08:21:39Z 2025-11-08T12:13:01Z ainyyy member/ainyyy 部分代码如下:

 } catch (Exception e) { log.error(e.getMessage(), e); return RestResult.fail("系统异常"); } 

日志文件中显示

2025-11-07 09:43:23.128 [http-nio-20001-exec-934] ERROR StoreOrderServiceImpl:557 - null java.lang.NullPointerException: null 

然后就结束了, 最近出了好多这种问题. 打印空指针,但是完全没有栈相关信息

]]>
为何 RestTemplate 无法定制请求 tag:www.v2ex.com,2025-11-07:/t/1171142 2025-11-07T02:14:30Z 2025-11-07T04:37:36Z cocong member/cocong 我们项目都是配置一个 RestTemplate bean ,然后所有外部请求都用它,现在有个需求的超时时间要求不一样,就得重新定义一个 bean ,又得怼一堆配置,麻烦,直接用 simpleClientHttpRequestFactory 又不能用到连接池,所以为何 RestTemplate 不支持对每个请求定制化,就像事务超时设置 @
Transactional(timeout = 3),每个都可以不一样,唯独这个外部请求没有这种功能,就感觉不太合理。

问了 AI ,可以用下面的方法,但感觉还是太麻烦了,不够简单优雅

步骤 1:创建一个全局共享的、带连接池的 CloseableHttpClient

public class PooledRestClient { private static final CloseableHttpClient httpClient; static { PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); cm.setDefaultMaxPerRoute(20); // 可选:设置空闲连接清理 httpClient = HttpClients.custom() .setConnectionManager(cm) .evictIdleConnections(60, TimeUnit.SECONDS) .build(); } // 核心方法:动态发起请求 public static ResponseEntity<String> exchange( String url, HttpMethod method, HttpEntity<?> requestEntity, Class<String> responseType, int connectTimeoutMs, int readTimeoutMs) { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( httpClient); factory.setConnectTimeout(connectTimeoutMs); factory.setReadTimeout(readTimeoutMs); RestTemplate restTemplate = new RestTemplate(factory); return restTemplate.exchange(url, method, requestEntity, responseType); } } 

步骤 2:在业务代码中直接调用(无需 Spring Bean )

// 动态构造请求头 HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", "Bearer " + token); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<>("{\"key\":\"value\"}", headers); // 发起带连接池的请求(每次 URL/Token/Body 都可不同) ResponseEntity<String> respOnse= PooledRestClient.exchange( "https://api.example.com/v1/data", HttpMethod.POST, entity, String.class, 3000, // connect timeout 10000 // read timeout ); 
]]> 日经吐槽:现在的 Java 语言真的有点令人恶心 tag:www.v2ex.com,2025-11-05:/t/1170596 2025-11-05T02:17:52Z 2025-11-07T09:30:01Z dog82 member/dog82 我之前在 java1.4/1.5/weblogic 时代做了多个 java 项目,后来转战 Go 语言多年,现在再返回来做 java 项目,有点 hold 不住了…… 1 、各种语法糖叠加起来,非常不直观。盐多了加水,水多了加盐,看类库的源码就像看甲骨文,脑子快拧成麻花了; 2 、整个技术体系 java+spring boot+cloud 太庞杂,学习成本和使用成本非常高。

]]>
新手 javaer 咨询几个问题 tag:www.v2ex.com,2025-10-31:/t/1169693 2025-10-31T06:12:41Z 2025-10-31T16:10:02Z dzdh member/dzdh 学了大概一周做了点桌面小玩意儿,做了几个 demo 网站,有些许疑惑有没有 java 前辈指点一下。

我知道 java ee 是个规范(这个规范是书面文档而已,是个倡议?还是一些具体的 API 且内置的?) 然后 JavaEE 交给了 Eclipse 现在叫 JakartaEE 我看到有一些包名是 jakarta.* 所以应该是一些具体的 jdk 内置的包?或三方包?

spring 是个什么东西?是类似 php 的 laravel ,python 的 fastapi ,go 的 gin ,rust 的 tokio 吗?只是在某个领域的事实标准,只是大多数人用,但不强制?

netty 又是个啥?文档说同等功能的还有 undertow 、tomcat-embed ,也只是基于内置 NIO 实现的“实时标准”框架吗?

]]>
自学 Java 看不懂报错信息和代码,有什么推荐 ai 拿来自学的吗? tag:www.v2ex.com,2025-10-30:/t/1169512 2025-10-30T10:47:15Z 2025-10-30T13:13:30Z Lucy2002 member/Lucy2002 算是半小白,求推荐自学能用来解释代码和报错的 AI 。🤗

]]>
用 netty 编写代理服务器,切换出口 IP,不能及时生效 tag:www.v2ex.com,2025-10-30:/t/1169319 2025-10-30T01:50:20Z 2025-10-30T07:04:07Z montaro2017 member/montaro2017 公司有一台服务器,有很多个公网 IP ,就想着能不能利用起来。

然后现在有一个任务是用浏览器打开指定网址,返回网页源代码,我就打算把这个服务器做成代理服务器。

本来是计划每个 IP 做一个代理服务器,代理服务器根据入口 IP 用对应的 IP 连接目标服务器。

开启每个浏览器的时候设置代理地址,比如 1.2.3.4:8639, 1.2.3.5:8639 这样 。

然后发现多开浏览器非常吃性能,要充分利用所有的公网 IP 得开几十个浏览器,这时候已经卡到动不了了,肯定不行。

所以我就想开 4 个浏览器,每个浏览器设置一个代理,然后通过接口去切换代理后端的出口。

代理服务器是用 netty 写的,逻辑改成了绑定不同端口,然后通过接口指定端口号和出口 IP ,来切换不同端口对应代理的出口 IP 。

其实就是存了一个 Map<Integer, String>,调接口修改这个 map ,netty 代理服务器连接目标服务器的时候使用出口地址去连接。

现在问题在于,调用接口切换出口 IP 后,日志显示已经使用新的出口 IP 了,但是访问查询 IP 的网站,还是使用之前的 IP ,好像要等一段时间才生效,这是什么问题,求各位大佬指教

@Log4j2 public class ProxyFrontendHandler extends SimpleChannelInboundHandler<FullHttpRequest> { private final AddressFunction addressFunction; public ProxyFrontendHandler(AddressFunction addressFunction) { this.addressFunction = addressFunction; } @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) { if (HttpMethod.CONNECT.equals(req.method())) { handleConnectRequest(ctx, req); return; } handleHttpRequest(ctx, req); } private void handleConnectRequest(ChannelHandlerContext ctx, FullHttpRequest req) { List<String> split = StrUtil.split(req.uri(), ":"); String host = CollUtil.getFirst(split); int port = Convert.toInt(CollUtil.get(split, 1), 443); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(ctx.channel().eventLoop()) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new RelayHandler(ctx.channel())); } }); ChannelFuture connectFuture; InetSocketAddress remoteAddress = new InetSocketAddress(host, port); InetSocketAddress sourceAddress = addressFunction.apply(ctx); if (sourceAddress != null) { log.info("Using outbound: {} | host: {}", sourceAddress, remoteAddress.getHostString()); cOnnectFuture= bootstrap.connect(remoteAddress, sourceAddress); } else { cOnnectFuture= bootstrap.connect(remoteAddress); } connectFuture.addListener((ChannelFutureListener) future -> { if (future.isSuccess()) { Channel outboundChannel = future.channel(); DefaultFullHttpResponse respOnse= new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.OK ); response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE); ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { try { ctx.pipeline().remove(HttpServerCodec.class); ctx.pipeline().remove(HttpObjectAggregator.class); ctx.pipeline().addLast(new RelayHandler(outboundChannel)); } catch (Exception ignored) { } }); } else { sendErrorResponse(ctx, "无法连接到目标服务器"); closeOnFlush(ctx.channel()); } }); } private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { String host = req.headers().get(HttpHeaderNames.HOST); if (host == null) { sendErrorResponse(ctx, "缺少 Host 头"); closeOnFlush(ctx.channel()); return; } String[] hostParts = host.split(":"); String targetHost = hostParts[0]; int targetPort = hostParts.length > 1 ? Integer.parseInt(hostParts[1]) : 80; // 修改请求 URI 为绝对路径 req.setUri(req.uri().replace("http://" + host, "")); req.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE); // 复制请求以避免在异步操作期间被释放 FullHttpRequest copiedReq = req.copy(); // 创建到目标服务器的连接 Bootstrap bootstrap = new Bootstrap(); bootstrap.group(ctx.channel().eventLoop()) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new HttpClientCodec()); ch.pipeline().addLast(new HttpObjectAggregator(1024 * 1024)); // 增加到 1MB ch.pipeline().addLast(new RelayHandler(ctx.channel())); } }); ChannelFuture connectFuture; InetSocketAddress remoteAddress = new InetSocketAddress(targetHost, targetPort); InetSocketAddress sourceAddress = addressFunction.apply(ctx); if (sourceAddress != null) { log.info("Using outbound: {} | host: {}", sourceAddress, remoteAddress.getHostString()); cOnnectFuture= bootstrap.connect(remoteAddress, sourceAddress); } else { cOnnectFuture= bootstrap.connect(remoteAddress); } connectFuture.addListener((ChannelFutureListener) future -> { if (future.isSuccess()) { future.channel().writeAndFlush(copiedReq); } else { closeOnFlush(ctx.channel()); } if (copiedReq.refCnt() != 0) { copiedReq.release(); } }); } private void sendErrorResponse(ChannelHandlerContext ctx, String message) { FullHttpResponse respOnse= new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, Unpooled.wrappedBuffer(message.getBytes()) ); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); ctx.writeAndFlush(response); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { if (cause instanceof SocketException) { closeOnFlush(ctx.channel()); return; } log.error(cause.getMessage()); closeOnFlush(ctx.channel()); } private void closeOnFlush(Channel ch) { if (ch.isActive()) { ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } 
@Log4j2 public class RelayHandler extends ChannelInboundHandlerAdapter { private final Channel relayChannel; public RelayHandler(Channel relayChannel) { this.relayChannel = relayChannel; } @Override public void channelActive(ChannelHandlerContext ctx) { ctx.read(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (relayChannel.isActive()) { relayChannel.writeAndFlush(msg).addListener((ChannelFutureListener) future -> { if (future.isSuccess()) { ctx.read(); // 继续读取数据 } else { future.channel().close(); } }); } else { closeOnFlush(ctx.channel()); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { log.error(cause); closeOnFlush(ctx.channel()); } private void closeOnFlush(Channel ch) { if (ch.isActive()) { ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } 
]]>
mysql 慢日志分析排查小工具 1.0.0 tag:www.v2ex.com,2025-10-28:/t/1168921 2025-10-28T07:18:45Z 2025-10-28T13:05:58Z lingerr member/lingerr 再发一次咯, 现在排行也支持分页了

后端开发日常少不了排查慢 SQL 。平时我都是用 mysqldumpslow 或 pt-query-digest 来分析日志,但命令行看着太不直观。 于是我写了一个可视化小工具,可以把慢日志结果直接展示成表格,并支持参数排序:

c:访问次数

l:锁定时间

r:返回记录数

t:查询时间

al:平均锁定时间

ar:平均返回记录数

at:平均查询时间

👉 在线体验地址: http://tool.linger.host/tools/mysql-analysis

欢迎大家体验下,有什么优化建议也欢迎留言交流!

]]>
Preferences.userNodeForPackage(Object.class)存储位置在哪里? tag:www.v2ex.com,2025-10-25:/t/1168328 2025-10-25T10:07:43Z 2025-10-25T12:48:25Z a33291 member/a33291
1. 每个独立的应用都用 Preferences.userNodeForPackage(Object.class)获取到的 Preferences 进行存储,则他们是相互隔离的还是会互相影响?
2. 存储位置在哪儿(win)? 我问 AI 和 google 都说在注册表的 HKEY_CURRENT_USER\Software\JavaSoft\Prefs\ 下,以包名为子键的位置,但是我测试运行发现并没有找到,但是的却优势存储成功,因为能读出来
3. 使用这个存储敏感信息(密码之类)合适嘛?

感谢 ]]>
vscode 中 augment code 怎么使用 mcp tag:www.v2ex.com,2025-10-25:/t/1168311 2025-10-25T07:43:10Z 2025-10-25T14:48:54Z pony2335 member/pony2335 现有个项目比较复杂,需要使用 mcp 功能的 mysql 连接到数据库,帮助大模型更好的理解业务,找了半天没找到教程,特意来 V2EX 求助

]]>
mysql 慢日志分析排查小工具 tag:www.v2ex.com,2025-10-24:/t/1168213 2025-10-24T10:36:30Z 2025-10-24T14:34:54Z lingerr member/lingerr 后端开发日常少不了排查慢 SQL 。平时我都是用 mysqldumpslow 或 pt-query-digest 来分析日志,但命令行看着太不直观。 于是我写了一个可视化小工具,可以把慢日志结果直接展示成表格,并支持参数排序( Top 10 ):

c:访问次数

l:锁定时间

r:返回记录数

t:查询时间

al:平均锁定时间

ar:平均返回记录数

at:平均查询时间

👉 在线体验地址: http://tool.linger.host/tools/mysql-analysis

欢迎大家体验下,有什么优化建议也欢迎留言交流!

]]>
Java 的一次编译到处运行在目前还有优势吗 tag:www.v2ex.com,2025-10-24:/t/1168179 2025-10-24T08:34:50Z 2025-10-27T00:56:00Z YanSeven member/YanSeven 现在学 Java 算 49 年入国军吗 tag:www.v2ex.com,2025-10-20:/t/1166867 2025-10-20T01:31:22Z 2025-10-20T12:00:44Z dzdh member/dzdh 本职是拍黄片 去 屁眼通红

]]>
推广一下自己刚撸的 IDEA 插件—Bean Copy 助手 tag:www.v2ex.com,2025-10-14:/t/1165225 2025-10-14T12:43:45Z 2025-10-23T19:47:35Z Aresxue member/Aresxue 插件名称:bean-copy-helper

插件地址:https://plugins.jetbrains.com/plugin/28686-bean-copy-helper
源码地址:https://github.com/Aresxue/bean-copy-helper

安装方式:在 Settings -> Plugins -> Marketplace 中输入 bean-copy-helper 检索即可找到该插件

这个插件一开始主要是写给自己用的,在阅读代码和排查 bug 的时候发现有很多项目使用了 Bean Copy ,Bean Copy 有时候确实很好用, 但是它也会带来一些困扰比如源对象通过 Bean Copy 赋值给目标对象以后通过 IDEA 的引用是找不到字段读取和写入( Bean Copy )的地方的,这个插件可以解决这个问题



可以看到我们可以对于Getter/Setter 方法或者字段使用属性复制范围查找,会认为一次 Bean Copy 是对源对象和目标对象同名且同类型的字段读取和写入(对于源对象来说是读取对于目标对象来说是写入)

为了避免对原有方法引用的污染所以采用类似Find Usages的方式,这样在跟踪某个字段的读取/写入时再也不会因为 Bean Copy 而被阻断了!!!

除此之外 Bean Copy 还经常被误用,这里也会对其做一些风险识别




最典型的场景就是同名字段类型不一致,实际上这个字段是没法被 Copy 过去的!!!

除此之外还集成了其它一些功能

可以预览源类和目标类属性的对比并生成相应注释

预览生成属性复制对应的Getter/Setter 代码


可以预览源类和目标类复制成功的属性并生成相应注释


而且使用中我常常发现字体时大时小有时候几乎无法观看,所以开放了字体大小自定义大家可自行修改

本插件永久免费,有需要的小伙伴自取。

]]>
几千万的数据量,层级权限下的列表展示页查询应该怎么设计? tag:www.v2ex.com,2025-10-13:/t/1164842 2025-10-13T06:39:18Z 2025-10-13T20:53:14Z lying500 member/lying500 各位大佬,想请教一下这个关于查询用户拥有权限的数据的问题,感觉这个挺常见的需求

业务场景:

假设一个业务表,数据量在几千万级。 需要为这个表提供一个列表展示页,要求按创建时间倒序分页。 主要是权限问题导致查询慢: 1 、用户可以查看自己创建的数据。 2 、用户可以查看自己所属群组的数据。 3 、群组的权限是可继承的、层级的:如果一个用户属于某个上级群组,那么他自动拥有查看其所有下级、下下级...群组内数据的权限。

问题: 如果权限简单,比如只看自己的数据,查询非常简单: WHERE user_id = ? ORDER BY create_time DESC LIMIT N 这种查询用索引就好解决。

但如果加入群组权限,查询的逻辑就变成了: SELECT * FROM a_large_table WHERE user_id = ? OR group_id IN (用户所属群组以及所有下级群组的 ID 列表) ORDER BY create_time DESC LIMIT N

这个查询就比较慢了 比如假定结构是这样:

xx

查询就变成了

SELECT * FROM project JOIN `group` ON project.group_id = `group`.id WHERE `group`.id IN (SELECT 用户关联的群组及其子群组 id) OR user_id = 20 ORDER BY project.created_at DESC LIMIT 10; 

这时候 (group_id, user_id, created_at) 也不好使;

问了 AI ,说了几个方案: 1 、应用层聚合/union user_id 和 group_id 的,建两个索引; 2 、冗余一张 用户能访问数据的表,直接查这个表; 3 、引入 es 之类的中间件;

想问一下实际大家是怎么处理的?

]]>
大家生产环境会一直开着 JFR 吗 tag:www.v2ex.com,2025-10-13:/t/1164788 2025-10-13T03:32:29Z 2025-10-13T06:37:35Z lidlesseye11 member/lidlesseye11 我看号称一般是 1%~ 2%,但是在测试环境试了下相差甚远。。
本来只用不到 0.5 核 CPU ,一打开 jfr 直接奔 1.5 核去了。
k8s 环境,jdk8 ,大佬们有什么思路吗 ]]>
有没有新版 Java 的佬(jdk25 和 21 这种), 上手还是走官方文档吗 tag:www.v2ex.com,2025-10-12:/t/1164621 2025-10-12T04:55:26Z 2025-10-21T22:32:05Z YanSeven member/YanSeven
看论坛撕逼大战经常有 Goer 和新 Javaer 的身影。

所以,产生好奇心理,想对比学习了解一下新版的 Java 。

楼主 Java 基础仅限于 n 年前上学期间的 Java 基本语法。 ]]>
Java 程序员面经怎么准备 tag:www.v2ex.com,2025-10-10:/t/1164118 2025-10-10T03:13:32Z 2025-10-10T10:45:37Z lame_chen member/lame_chen Java 25 后的时代:像写 Python 一样写 Java tag:www.v2ex.com,2025-09-27:/t/1162247 2025-09-27T16:13:18Z 2025-09-29T09:28:59Z Cbdy member/Cbdy Compact Java App - 像写 Python 一样写 Java

项目地址: https://github.com/alchem-x/compact-sb

什么是 Compact Java App ?

Compact Java App 是基于 Java 25 新特性( JEP 512 )的编程方式,让你可以像写 Python 一样写 Java 程序:

// 传统的 Java Hello World public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } // Compact Java App Hello World void main() { IO.println("Hello, World!"); } 

核心优势

当前项目介绍

这个仓库演示了 Compact Java App 的实际应用 - 一个轻量级的 Web 服务器实现。

项目结构

compact-sb/ ├── Lu.java # 紧凑 Java App 主程序 ├── CompactSB.java # Web 服务器核心 ├── lib/ # 依赖库 └── README.md 

快速开始

  1. 确保 Java 25+已安装
java -version # 需要 Java 25 或更高版本 
  1. 运行应用
java Lu.java && java -cp "lib/*" CompactSB.java 
  1. 访问 Web 服务 打开浏览器访问 http://localhost:8080/

核心代码示例

Lu.java - 紧凑 Java App 的精髓:

void main() { // 简洁的 Web 服务器启动 IO.println("Starting Compact Web Server..."); // 自动导入所有 java.base 类 var server = new Server(); server.start(8080); IO.println("Server running at http://localhost:8080/"); } 

为什么选择 Compact Java App ?

  1. 教学友好 - 第一天就能写出实用的程序
  2. 脚本化 - 用 Java 写脚本,享受强类型和优秀性能
  3. 零配置 - 无需复杂项目结构和构建工具
  4. 生产就绪 - 可平滑扩展到企业级应用

与传统 Java 对比

特性 传统 Java Compact Java App
Hello World 5 行,4 个概念 3 行,1 个概念
依赖管理 需要 Maven/Gradle 直接运行源文件
学习曲线 陡峭 平缓
开发速度 快速
运行时性能 优秀 同样优秀

应用场景

技术细节

下一步计划

这个项目展示了 Compact Java App 在 Web 开发中的应用。未来可以:

  1. 添加更多路由处理功能
  2. 集成模板引擎
  3. 支持静态文件服务
  4. 添加数据库连接示例
  5. 创建 RESTful API 演示

相关资源


Compact Java App 让 Java 重新变得简单优雅,同时保持其强大的生态系统。未来已来,让我们一起拥抱这个全新的 Java 时代! 🚀

本项目是 Compact Java App 理念的实践演示,展示了如何用简洁的代码构建实用的应用程序。

]]>
兄弟们,请求个 netty 的线程问题 tag:www.v2ex.com,2025-09-20:/t/1160806 2025-09-20T19:30:15Z 2025-09-21T23:04:31Z zhazi member/zhazi @Component @RequiredArgsConstructor public class WebSocketServer implements ApplicationRunner, DisposableBean { @Value("${netty.port}") private int port; private final EventLoopGroup bossGroup = new NioEventLoopGroup(); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); private final ServerBootstrap b = new ServerBootstrap(); private final Map<String, Channel> map = new HashMap<>(); @Override public void destroy() { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } @Override public void run(ApplicationArguments args) throws Exception { b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new WebSocketServerProtocolHandler("/ws", true, 3000L)); pipeline.addLast(new WebSocketFrameHandler(map)); } }); ChannelFuture future = b.bind(port).sync(); System.out.println("WebSocket server started on port " + port); future.channel().closeFuture().sync(); } } @Slf4j public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> { private final Map<String, Channel> map; public static final AttributeKey<String> URI_ATTRIBUTE_KEY = AttributeKey.valueOf("URI"); public WebSocketFrameHandler(Map<String, Channel> map) { this.map = map; } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) { WebSocketServerProtocolHandler.HandshakeComplete handshakeComplete = (WebSocketServerProtocolHandler.HandshakeComplete) evt; Channel currentChannel = ctx.channel(); String uri = handshakeComplete.requestUri(); currentChannel.attr(URI_ATTRIBUTE_KEY).set(uri); Channel exist = map.get(uri); if (Objects.isNull(exist)) { map.put(uri, currentChannel); log.info(new Message(uri, currentChannel.id().toString(), 1).toString()); } else { //无效 exist.close().sync();//明确在 close 执行完成后在重新上线,但是好像没生效一样,直接就输出上线! 1= 上线,0= 下线 map.put(uri, currentChannel); log.info(new Message(uri, currentChannel.id().toString(), 1).toString()); //无效 //exist.close().addListener(future -> log.info(new Message(uri, currentChannel.id().toString(), 1).toString())); //无效 //exist.close().sync().addListener(future -> log.info(new Message(uri, currentChannel.id().toString(), 1).toString())); } } else { super.userEventTriggered(ctx, evt); } } @Override public void channelInactive(ChannelHandlerContext ctx) { Channel channel = ctx.channel(); String uri = channel.attr(URI_ATTRIBUTE_KEY).get(); log.info(new Message(uri, channel.id().toString(), 0).toString()); } }

日志输出:

2025-09-21 03:16:54.669 INFO 30008 --- [ntLoopGroup-5-1] org.example.WebSocketFrameHandler : Message{uri='/ws/abc_123', sessiOnId='86aeadad', status=上线} 2025-09-21 03:16:58.837 INFO 30008 --- [ntLoopGroup-5-2] org.example.WebSocketFrameHandler : Message{uri='/ws/abc_123', sessiOnId='fa3a5fbb', status=上线} 2025-09-21 03:16:58.838 INFO 30008 --- [ntLoopGroup-5-1] org.example.WebSocketFrameHandler : Message{uri='/ws/abc_123', sessiOnId='86aeadad', status=下线} 

我用 netty 提供的 websocket 服务,想达到新设备踢出老设备的在线状态, 但是控制不好状态

预期的效果:

日志输出:

但是现在看结果是错误的顺序。

想在这个服务里保证状态的正确,我尝试使用自定义 eventGroup 并且设置线程数 1 来执行代码也不行,也尝试跟 ai 沟通了半宿也研究明白

netty-all 的版本是 4.2.6.Final

]]>
JDK 25 发布了, LTS 版本 tag:www.v2ex.com,2025-09-17:/t/1159798 2025-09-17T00:53:56Z 2025-09-19T08:54:51Z Ayanokouji member/Ayanokouji
https://openjdk.org/projects/jdk/25/

Features

470: PEM Encodings of Cryptographic Objects (Preview)
502: Stable Values (Preview)
503: Remove the 32-bit x86 Port
505: Structured Concurrency (Fifth Preview)
506: Scoped Values
507: Primitive Types in Patterns, instanceof, and switch (Third Preview)
508: Vector API (Tenth Incubator)
509: JFR CPU-Time Profiling (Experimental)
510: Key Derivation Function API
511: Module Import Declarations
512: Compact Source Files and Instance Main Methods
513: Flexible Constructor Bodies
514: Ahead-of-Time Command-Line Ergonomics
515: Ahead-of-Time Method Profiling
518: JFR Cooperative Sampling
519: Compact Object Headers
520: JFR Method Timing & Tracing
521: Generational Shenandoah


本帖依旧不欢迎刷 JDK 8 梗,JDK 8 已经发布 10 多年了。 ]]>
使用 Java 技术栈生成二维码 tag:www.v2ex.com,2025-09-13:/t/1159004 2025-09-13T10:37:26Z 2025-09-13T12:37:26Z Honwhy member/Honwhy 一般使用zxing 库就可以生成二维码了,但是要注意一个重要参数,ErrorCorrectionLevel 纠错能力等级,等级越高,内容码点越密集,纠错能力当然也越强(即使被遮挡了一部分也能还原)

<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.5.2</version> </dependency> 
public enum ErrorCorrectionLevel { L(1), M(0), Q(3), H(2); } 

可以发现纠错等级越高,生成二维码的码点越密集。

左边 level=0 ,右边 level=3

| | |

如果为了生成更好一点的二维码,建议使用qrgen

<dependency> <groupId>com.github.aytchell</groupId> <artifactId>qrgen</artifactId> <version>3.0.0</version> </dependency> 

创建二维码

 private BufferedImage createRoundedQRCodeImage(String url, int width, int level) throws QrConfigurationException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, WriterException { QrCodeRenderer qrCodeRenderer = new QrCodeRenderer(PixelStyle.ROWS, MarkerStyle.ROUND_CORNERS); ColorConfig colorCOnfig= new ColorConfig(new RgbValue(0, 0, 0), new RgbValue(255, 255, 255)); Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.ERROR_CORRECTION, getErrorCorrectionLevel(level)); return qrCodeRenderer.encodeAndRender(url, colorConfig, width, width, hints); } 

效果

--- 关于作者 ---

]]>
Springboot 项目部署到 docker 无法连通数据库 tag:www.v2ex.com,2025-09-12:/t/1158782 2025-09-12T05:55:55Z 2025-09-04T19:54:21Z puremaker member/puremaker macbook 装了 orbstrack ,用 docker 部署了 mysql 、redis 和 centos 。

我现在有两个 springboot 项目,这两个项目本地开发连接 docker 的 mysql 都没有问题。

然后都部署到同一个 centos 虚拟机里,都使用的是本电脑的局域网 ip 连接的数据库,一个可以正常访问到数据库,一个就访问不到,确认了链接 url 除了库名都是一样的,想请教一下这能是什么原因呢?

]]>
有写 Java 的么,你们的 jdk 还是用 1.8 么 tag:www.v2ex.com,2025-09-05:/t/1157327 2025-09-05T07:14:07Z 2025-09-12T15:09:29Z DeepSIeep member/DeepSIeep 查了一下 jdk ,jdk21 。最新的已经出道 24 了。之前听说 1.8 以后收费,现在后面已经有很多免费版本了。 ]]> 即时通讯工具推荐 tag:www.v2ex.com,2025-09-03:/t/1156824 2025-09-03T07:18:06Z 2025-09-07T02:16:41Z rainfy member/rainfy 公司想在自营产品中嵌入一个即时通讯工具,希望支持发文字、语音、视频。 希望支持 sdk 接入,ui 自己画。 求各位大佬推荐~

]]>
cursor 替换 idea 作为 Java 主力开发工具 tag:www.v2ex.com,2025-08-19:/t/1153539 2025-08-19T13:21:49Z 2025-08-24T20:47:49Z lookupsky member/lookupsky cursor 占用内存相对来说比 idea 小(吐槽一下公司配置的 32G 都不够用,有时候要研究关掉一些软件腾出内存),其次代码内嵌提示和 agent 及代码分析极大提升开发效率而且响应快(对比 codeium),现在 vscode 生态的软件对 java 开发的支持度还是挺高的

核心插件

Extension Pack for Java 和 Spring Boot Extension Pack

插件配置 setting.json "java.configuration.runtimes": [ { "name": "JavaSE-1.8", "path": "D:\\xxxx\\xxxx\\jdk8-271", "default": true //项目默认运行 jdk 版本 }, { "name": "JavaSE-17", "path": "D:\\xxxx\\xxxx\\jdk-17.0.3.1" } ] // Extension Pack for Java 插件服务运行在高版本 jdk 上(jdk9+) "java.jdt.ls.java.home": "D:\\xxxx\\xxxx\\jdk-17.0.3.1", // Spring Boot Extension Pack 插件服务运行在高版本 jdk 上(jdk9+) "spring-boot.ls.java.home": "D:\\xxxx\\xxxx\\jdk-17.0.3.1", // 配置 maven 操作 "java.configuration.maven.userSettings": "D:\\xxxx\\settings.xml", //自定义仓库存储地址 "java.configuration.maven.globalSettings": "D:\\xxxx\\settings.xml",//自定义仓库存储地址(全局) "maven.executable.path": "D:\\xxxx\\apache-maven-3.8.2\\bin\\mvn", //自定义 mvn 命令地址 

辅助插件:

git graph //代码管理 IntelliJ IDEA Keybindings //idea 快捷键映射,ctrl+shift+p 打开"键盘快捷方式"映射自定义修改 mybatis-tools //mybatis 或 plus 的文件.xml 和.java 快速跳转 Copy Reference //快速复制类或方法的包路径 

其他:

]]>
OracleJDK 21 收费问题 tag:www.v2ex.com,2025-08-19:/t/1153444 2025-08-19T07:07:58Z 2025-08-19T10:47:59Z oblax member/oblax 这是官网的写法: Java SE Development Kit 21.0.8 downloads JDK 21 binaries are free to use in production and free to redistribute, at no cost, under the Oracle No-Fee Terms and Conditions (NFTC).

JDK 21 will receive updates under the NFTC, until September 2026, a year after the release of the next LTS. Subsequent JDK 21 updates will be licensed under the Java SE OTN License (OTN) and production use beyond the limited free grants of the OTN license will require a fee.

严格翻译的话,似乎收费的只有“Subsequent JDK 21 updates”,只要不更新就不收费,问了几个大模型也都这么说。 但是在网上搜索,似乎是按时间收费的说法居多,即三年免费期一过就会开始收费。

]]>
有没有比较了解 GraalVM 的,想问下适合本地开发调试吗? tag:www.v2ex.com,2025-08-13:/t/1152181 2025-08-13T11:16:32Z 2025-08-13T22:17:40Z NotoChen member/NotoChen 目前在用的是 bellsoft liberica jdk

之前也用过 IBM 的 OpenJ9

其他各类厂商的 JDK 也多多少少都试过,感觉并没有很明显的提升

甚至有的 JDK 跑出来,还有编码问题,日志都是乱码的

还有类似 SSL 的支持兼容问题

看各类文档,总说启动快快快,内存省省省

想知道是不是属实

总的来说,目前用的 bellsoft liberica jdk 基本没出过问题,我的 mac ,windows 还有 linux 服务器,几乎都是用的这个,甚至 docker 镜像也都是找的 bellsoft

]]>
spring boot3.0 应该怎么选择工作流 tag:www.v2ex.com,2025-08-13:/t/1152091 2025-08-13T06:08:07Z 2025-08-13T12:26:34Z vdrapb member/vdrapb 最近从零开发了一个项目,项目中经常会遇到审核相关的东西。我想着能不能引入一个工作流到系统中,设计系统每个业务的审核流程,以前没搞过工作流的项目,怎么使用也不太熟悉,请问各位大佬有没有什么好的建议,或者有没有开源的项目可以学习一下

]]>
学习 Jackson 封装时候遇到一个泛型问题希望大牛能帮忙解惑 tag:www.v2ex.com,2025-08-12:/t/1151881 2025-08-12T09:28:04Z 2025-08-13T18:21:19Z puremaker member/puremaker 封装一个转指定实体类 list 的方法,有如下两种

public static <T> List<T> parseList(String jsonString, Class<T> elementClazz) throws Exception { ObjectMapper mapper = new ObjectMapper(); TypeReference<List<T>> typeReference = new TypeReference<List<T>>() {}; return mapper.readValue(jsonString, typeReference); } 
public static <T> List<T> parseList(String jsonString, TypeReference<List<T>> typeReference) throws Exception { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(jsonString, typeReference); } 
public static void main(String[] args) throws Exception { String jsOnListStr= "[{\"username\":\"pure1\",\"phone\":\"18xxx\"},{\"username\":\"pure2\",\"phone\":\"19xxx\"}]"; List<User> userList1 = parseList(jsonListStr, User.class); List<User> userList2 = parseList(jsonListStr, new TypeReference<List<User>>(){}); } 

两个转完的 list 里,第一个 list 里的对象在断点里看实际上是个LinkedHashMap ,是无法正常调用实体类的 get 方法的。第二个 list 里的对象就是真正的User。所以我分别去看了两个方法的 typeReference 对象,第一个方法的 typeReference 对象里的_type 值为“java.util.List<T>”,第二个方法里的 typeReference 对象里的_type 值为“java.util.List<xxx.xxx.entity.User>”。虽然第二个方法可以正常使用,但是封装肯定是为了简便,以TypeReference<List<T>> typeReference作为入参感觉很奇怪,我底层了解的不多,我的认知里在入参的时候 new 一个 TypeReference 和在方法里 new 一个 TypeReference 应该是一样的才对。希望有大牛帮我解惑,或者是不是我第一个方法的代码写的有问题。

在此先谢谢各位了!!!

]]>
写了 3 天 go,我想念 Java 了 tag:www.v2ex.com,2025-08-08:/t/1151046 2025-08-08T08:07:06Z 2025-08-11T21:37:19Z exploretheworld member/exploretheworld


不适合写复杂业务,一个注解能搞定的事情,必要要去自己弄,增加太多不必要的工时。



只能说搞到最后大家都是在拆东墙补西墙,大家只能按照实际情况各取所需,所谓的银弹根本不存在。 ]]>
高德 Web 接口 IP 定位的一个坑,希望大家别踩。 tag:www.v2ex.com,2025-08-05:/t/1150093 2025-08-05T06:57:03Z 2025-08-06T03:34:22Z kelololy member/kelololy 背景: 系统中记录 打卡功能,需要记录 ip 和地址,因为买的有高德的基础 vip ,所以选择了高德定位接口:

问题: 用户发现自己打卡位置在焦作,但系统显示位置在信阳;通过网页端高德 api ,发现高德的接口确实返回错误

高德 API: https://restapi.amap.com/v3/ip?key=xx&ip=xx ip 地址为:223.90.35.17 (实际为河南焦作,但高德返回为信阳)

lz 除了高德,分别试了腾讯、ip138 、ip2region(开源) 这三者都没问题

目前已经将该问题提给客服,客户说是会给产品团队;

** 这边给需要使用地图服务和已经使用高德 api 服务的各位提个醒 **

]]>
为什么 Oracle 有些 JavaSE 版本收费有些不收费?最新的反而不收费 tag:www.v2ex.com,2025-08-02:/t/1149518 2025-08-02T13:55:09Z 2025-08-02T15:07:42Z nnegier member/nnegier
刚刚我打开 Oracle Java Downloads 页面,看到最新版本 24 和 21 ( LTS )均不收费,我往下翻,翻到 11 又要收费。

https://www.oracle.com/cn/java/technologies/downloads/#java21
https://www.oracle.com/cn/java/technologies/downloads/#java11 ]]>
请教关于私有化前后端一键部署的一些问题。 tag:www.v2ex.com,2025-07-31:/t/1149095 2025-07-31T09:55:52Z 2025-07-31T20:56:21Z heiya member/heiya
  • 技术选型:前端是 Vue ,后端是 SpringBoot+Mysql+Redis+Minio ( OSS ),版本控制是 git ,项目管理是 maven 。
  • 要求:能做到在客户不通外网的普通电脑主机上进行一键部署,开箱即用;且还有一个要求,假设后端有 A 、B 、C 、D 四个功能,每个客户需要的功能是 A 、B 、C 、D 四个功能的不同组合,如果需要 A 、B,则不能包含 CD 的代码,让删掉这些代码!!!但很可能逻辑有交织。
  • 自己能想到的办法:1.对于一键化部署需要通过 docker 、docker compose 去做,缺点就是需要安装这些东西,但客户很多都是非技术人员。2.不同功能的组合,代码不能删除,通过拆分不同模块的办法进行解耦,对逻辑有交织的部分面向接口编程。最后在打包时根据需求进行模块的聚合。
  • 这是目前自己能够想到的,还有什么更优解吗?请赐教
  • ]]>
    谁知道 trae 国际版 pro 用户兑换 solo 模式的激活码通道在那里 tag:www.v2ex.com,2025-07-19:/t/1146309 2025-07-19T07:03:15Z 2025-07-22T20:07:18Z XDiLa member/XDiLa 今天 trae 更新了 solo 模式 看起来很好用,虽然还说了 pro 用户可以兑换使用,但是没找到通道。你们谁知道吗

    ]]>
    不懂就问 就 Java 来说 APP 的后端开发 和 web 的后端开发有区别吗 tag:www.v2ex.com,2025-07-18:/t/1146086 2025-07-18T04:35:40Z 2025-07-18T18:06:12Z Dmumuxi member/Dmumuxi 兄弟们 现在 windows 下管理多版本的 jdk 最优解是什么呢 tag:www.v2ex.com,2025-07-16:/t/1145667 2025-07-16T13:06:24Z 2025-08-01T02:25:11Z Ghostisbored member/Ghostisbored 1 、直接在 windows 下安装多个版本 但是这样会出现一个问题 高版本的 jdk 会覆盖低版本的一些环境变量
    比如 idea 直接读到的是高版本 哪怕切换到低版本的路径也有一些问题
    2 、wsl 方案 在 wsl 中使用 sdkman 安装多版本 idea 指向对应的 jdk 安装路径 ,但是这样有非常多的兼容问题 比如 windows 读取 liunx 的文件路径经常读取不到 maven 编译也有各种兼容问题
    所以想问问大家的大家怎么管理的 谢谢 ]]>
    请教关于 spring-boot-devtools 的问题 tag:www.v2ex.com,2025-07-04:/t/1143059 2025-07-04T08:33:00Z 2025-07-10T16:05:32Z JYii member/JYii
    而且重启依旧如此,只能 mvn clean install 后启动应用才正常。

    观察日志,修改代码编译后,devtools 会重启应用,没任何有价值的日志,跟正常启动差不多,打开 debug 日志,交给 gemini 分析:

    您的项目中存在某个组件(很可能是一个我们没找到的、行为不当的自定义线程池或第三方库),这个组件导致了 Spring 应用上下文 无法被干净地关闭。
    * 当 DevTools 尝试进行 Restart 时,它在这个“关闭上下文”的步骤上失败了(正如我们日志中看到的,数据库连接池没有被关闭),导致整个应用处于一种“僵尸”状态。

    尝试找了项目中可能未正确关闭的代码,线程池、threadlocal 等等,还有第三方依赖,这属实范围难度有点大,索性就把 devtool 注释了。
    关闭后,通过 idea 的自动编译,反而可以正常工作了。

    这个 devtool 是我没有使用好吗,搜了下主要是自动重启、静态资源刷新(前后端分离直接忽略)

    环境:idea 最新版,jdk17 ,springboot 最新版 ]]>
    胡思乱想(针对企业的 ai 平台应用) tag:www.v2ex.com,2025-06-30:/t/1142096 2025-06-30T15:06:07Z 2025-07-01T06:18:27Z Misty99 member/Misty99 想做一个针对企业的 ai 平台应用

    1. 通过聊天的形式发起一些业务操作
    2. 数据报表生成(各类文档)

    简化一些通用性的操作吧 不用登录对应的系统就可以进行一些操作 企业多系统之间也可以有关联

    ]]>
    打算做一个 Docker 应用,用 Java 写,数据存储选型求有经验的大佬分析。 tag:www.v2ex.com,2025-06-27:/t/1141489 2025-06-27T08:03:13Z 2025-06-27T15:18:18Z cookii member/cookii 面向普通人,不考虑把程序做复杂化,考虑用嵌入式数据库,比如 H2 ,开箱即用,一个镜像即可搞定。

    主要是用来储存用户的一些配置信息,还有程序的运行日志(日志可能会到 100k/day 级别),定期清理日志(90day/180day?)

    目前有几个疑问:

    目标是让程序尽可能的可靠,可以容忍日志丢失之类的情况,但程序至少需要正常运行。

    ]]>
    Java 中 ThreadLocalMap 里对值的引用为什么不是弱引用?难道会出现 ThreadLocalMap.Entry.Key 也就是 ThreadLocal 应当销毁,但值不应当销毁的情况? tag:www.v2ex.com,2025-06-27:/t/1141413 2025-06-27T03:10:34Z 2025-06-27T03:57:07Z BraveXaiver member/BraveXaiver
    既然如此那后者不应该也一起被回收,进而使用弱引用?

    谢谢 ]]>
    SpringCloudGateway 已经支持了接口的限流和熔断降级,那么还需要在业务层接口做熔断降级限流处理吗? tag:www.v2ex.com,2025-06-25:/t/1141061 2025-06-25T12:45:41Z 2025-06-29T15:18:36Z qinghuazs member/qinghuazs 咨询一个技术问题,SpringCloud Gateway 已经支持了接口的限流和熔断降级,那么还需要在业务层接口做熔断降级限流处理吗? 假设内部接口调用也走网关的情况下,网关层已经能够做到业务层的限流降级,此时业务层可以不关注限流降级的这类非功能性需求,重点关注业务逻辑即可; 但是另一方面,业务层做限流降级的话,可以对接口进行更精细化的控制,但是对代码是有入侵性的,而且还得兼顾动态化配置,而网关支持动态配置也更容易。 希望能看看大家都是怎么做的?

    ]]>
    hutool 还能继续使用吗?怕投毒。有没有替代的,或者最后一个可用版本是什么 tag:www.v2ex.com,2025-06-22:/t/1140263 2025-06-22T09:57:49Z 2025-06-23T07:53:26Z xiguaprince member/xiguaprince 旧闻: Vert.x 5 发布 tag:www.v2ex.com,2025-06-21:/t/1140092 2025-06-21T06:13:06Z 2025-06-22T03:35:19Z yazinnnn0 member/yazinnnn0 https://vertx.io/blog/eclipse-vert-x-5-released/

    What's new in Vert.x 5
    Embracing the future based model
    OpenAPI & Vert.x OpenAPI Router
    io_uring support


    vertx 以性能强悍+难写难理解著称, 貌似没有成为过大公司的主流框架, 国内(圆神除外)也没听说过有公司大规模使用过 ]]>
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86