当前位置: 首页 > article >正文

Google Mug库——一个现代的通用工具库

Google Mug库是我维护的一款开源Java工具库。包含了一些近几年在Google内部的labs代码库中被广泛使用的工具集成了一些经实践验证很成功也比较成熟了的新工具。今天我先介绍Mug的StringFormat库。这个库的初衷是为了解决很多很常见的从字符串中抽取信息的问题。比如某个文件名会是这样一个人格式 /usrs/{user}/logs/{year}/{month}/{day}/{name}.log。那么给定一个这个格式的文件名怎么从中抽取这些占位符对应的值呢为什么不用正则表达式传统上大家会用正则来处理这种信息抽取。javaprivate static final Pattern LOG_FILE_PATTERN Pattern.compile(/usrs/(?user[^/])/logs/(?year\d{4})/(?month\d{2})/(?day\d{2})/(?name.)\.log);Matcher matcher LOG_FILE_PATTERN.matcher(filePath);if (matcher.matches()) {String user matcher.group(user);String year matcher.group(year);String month matcher.group(month);String day matcher.group(day);String name matcher.group(name);...}这样做的好处是正则嘛大家都会。坏处呢正则表达式往往可读性较差在Java里写有时候是两个反斜线还是四个反斜线也容易搞混了。对复杂的匹配规则这么做是值得的但是对上面这种常见的格式固定的抽取就显得杀鸡用牛刀代码维护起来就会难一些。另外为了效率正则的Pattern 对象往往要定义成static final来一次性编译regex。但是带来的问题是pattern和具体parse的代码可能会分开得比较远比如隔上几个翻页。这样写 group(name)这种的时候 你可能要上滚去找具体的组名字如果写错了组名字或者有时候图省事都不用命名capture group直接用魔法数索引编译也不会报错读代码的时候尤其是调试的时候也可能要上下滚动对照pattern和底下的抽取代码的一致性。还有一个问题一般人可能不会在意但是如果你的代码要跑在高可用性高吞吐量的服务器上的话regex其实是有稳定性的缺陷的。Java的regex实现用的是NFA回溯这种实现的特点是它可能对大多数输入都很快但是对某些特殊输入或者恶意的regex-dos攻击可能会造成指数级的“灾难回溯”。真实的例子Stack Overflow 2016: a regex used to extract comment anchors caused a global outage due to backtracking explosion (postmortem).Cloudflare 2019: 一个有问题的regex造成cpu超负载大量服务器宕机 (incident report).用StringFormat抽取格式化信息这大概算一个80-20问题。对80%的简单但普遍的情况Google Mug的StringFormat 是一个更方便更安全高效的工具。这个抽取可以用以下代码直观和简单地做到javaprivate static final StringFormat LOG_FILE_FORMAT new StringFormat(/usrs/{user}/logs/{year}/{month}/{day}/{name}.log);LOG_FILE_FORMAT.parse(filePath, (user, year, month, day, name) - ...);它直接用我们上面最直观的日常用到的带占位符的格式串然后直接抽取。返回的是一个OptionalT这样就如果格式不匹配就显式返回空帮助使用者不会忘记处理失败情况。或者如果你知道这个格式肯定匹配那么就用 parseOrThrow()。这么做的好处有格式串直观可读。抽取部分代码简洁不需要依赖魔法数没有组名字写错的风险。库自带ErrorProne的编译期插件如果你在lambda里把参数顺序搞错了比如 (year, month, day, user, name),编译器会报错。 这就让你可以放心地把StringFormat定义成static final然后在别的地方重用而不需担心一致性问题。在运行时它用的是简单的String.indexOf(), 一般比regex要更高效也没有回溯问题。禁用NFA多说一句。因为对服务器可靠性的考量还记得前几天的Google全球宕机吗虽然那个是C UB的锅但是可靠性是大型互联网公司都无法忽视的普遍问题Google内部已经原则上禁用JDK的regex因为NFA虽然对平均情况的性能不错但是遇到某些特殊的输入甚至恶意攻击可能会指数级回溯。目前谷歌的替代品是用JNI包裹了一个C的RE2的实现。但是benchmark跑下来在JNI的边界传递输入输出的代价高昂所以比如你的输入字符串很大或者你要用regex来做抽取效率都不高。我现在在写一个静态分析帮助把一些本来没必要用regex的用例迁移到StringFormat或者是Substring上后者是一个比Apache StringUtils更灵活更强大可读性更好的字符串工具类支持链式调用的。比如^projects/(?project[^/])/locations/(?location[^/])/jobs/(?job[^/])$ 这种蛋疼的regex完全可以写成:javanew StringFormat(projects/{project}/locations/{location}/jobs/{job}).parseOrThrow(input, (project, location, job) - ...);高效易读没有灾难性回溯。多次抽取前面的示例是完整匹配后抽取。你也可以用 scan()方法来实现在字符串里寻找符合这个格式的子串。比如以下代码扫描markdown文件找到所有的链接java体验AI代码助手代码解读复制代码ListMarkdownLink links new StringFormat([{title}]({url})).scan(markdown, (title, url) - new MarkdownLink(title, url)).toList();scan()返回的是一个懒加载的StreamT所以你也可以比如用findFirst(), limit(n)anyMatch()来中途退出而不用付全字符串扫描的代价。用StringFormat代替String.format()StringFormat是个双向的API。除了抽取还支持格式化字符串支持 format(Object...)方法。上面提到的编译期插件也用在了format()。比如java体验AI代码助手代码解读复制代码String logFile LOG_FILE_FORMAT.format(user, year, month, day, name);跟抽取类似如果你把参数的个数或者顺序写错了编译器会报错。对比JDK的String.format(), 如果你有一个格式串要多次使用那么你可能想要把它定义为 static final 。但是这样一来在调用String.format() 的时候就有风险把参数顺序和个数搞错造成逻辑错误。而用StringFormat就没有这个问题了。你可以放心地复用private static final的StringFormat常量。从谷歌内部代码情况来看用StringFormat来做格式化比做抽取还要常见。你也可以做所谓的rewrite。比如如果要把user的部分改名字就可以做javaMapString, String renamings ...;String newFile LOG_FILE_FORMAT.parseOrThrow(filePath,(user, year, month, day, name) -LOG_FILE_FORMAT.format(renamings.get(user), year, month, day, name)));最后运行效率上Java 17以前的String.format()内部用的是正则表达式去parse这个格式串效率相当低。换用StringFormat.format()后据benchmark大约有几十倍的提升。即使是Java 17之后StringFormat预分配成static final的话也比JDK的快5倍左右。原文链接https://juejin.cn/post/7554322871418814499

相关文章:

Google Mug库——一个现代的通用工具库

Google Mug库是我维护的一款开源Java工具库。包含了一些近几年在Google内部的labs代码库中被广泛使用的工具,集成了一些经实践验证很成功也比较成熟了的新工具。今天我先介绍Mug的StringFormat库。这个库的初衷是为了解决很多很常见的从字符串中抽取信息的问题。比如…...

Rust量化交易框架clawtrader:高性能与内存安全的工程实践

1. 项目概述:一个用Rust构建的量化交易框架最近几年,量化交易的门槛似乎在不断降低,但真正能稳定跑起来的系统,其技术栈的复杂度和对性能的极致要求,依然让很多个人开发者和中小团队望而却步。传统的方案,无…...

U 盘安装 ESXi 8.0 进度条卡住?核心修复方案与全流程实操指南

本文针对 U 盘安装 VMware ESXi 8.0 时高频出现的安装进度条卡死、无法继续的痛点问题,详解故障的核心触发根源,重点讲解 2 个经过生产环境验证的修复方案 —— 更换服务器原生 USB 3.0 接口、使用 Rufus 工具 DD 模式制作安装 U 盘,同时补充…...

次元画室Windows部署保姆级教程:5分钟解决Python路径与权限问题

次元画室Windows部署保姆级教程:5分钟解决Python路径与权限问题 你是不是也遇到过这种情况?在网上看到一个超酷的AI绘画工具“次元画室”,兴冲冲地想在Windows电脑上装一个,结果刚打开命令行就懵了——Python命令找不到、C盘空间…...

为AI智能体构建可治理的语义执行层:安全、合规与可控实践

1. 项目概述:为AI智能体系统构建一个可治理的“语义执行层”如果你正在构建或使用基于大语言模型的智能体(Agent)系统,比如让AI帮你自动执行代码、调用API、处理文件,那么你肯定遇到过这个核心难题:如何确保…...

Monolito-V2:AI工作流编排框架,从模块化设计到生产实践

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫 Monolito-V2。这名字听起来有点抽象,但说白了,它就是一个帮你把各种不同的 AI 模型、工具和数据处理流程,像搭积木一样组合成一个统一工作流的框架。你可以把它想象成一…...

AI衣品升级报告-02-女装

...

5分钟快速上手!Draw.io电子工程绘图库完整指南

5分钟快速上手!Draw.io电子工程绘图库完整指南 【免费下载链接】Draw-io-ECE Custom-made draw.io-shapes - in the form of an importable library - for drawing circuits and conceptual drawings in draw.io. 项目地址: https://gitcode.com/gh_mirrors/dr/Dr…...

AI衣品升级报告-01-男装

...

Murmur:开源全局语音输入工具,解放开发者双手

1. 项目概述:解放双手的全局语音输入工具 作为一名长期与代码和文档打交道的开发者,我一直在寻找一种能让我在思考时双手不离开键盘,又能高效输入文字的方法。传统的语音输入工具要么绑定在特定应用里,要么需要频繁切换窗口&…...

Oumuamua-7b-RP惊艳效果:用户说‘お疲れ様でした’后自动触发关怀回应行为链演示

Oumuamua-7b-RP惊艳效果:用户说お疲れ様でした后自动触发关怀回应行为链演示 1. 项目概述 Oumuamua-7b-RP 是一款专为日语角色扮演对话设计的Web界面大语言模型,基于Mistral-7B架构开发。这个模型特别擅长理解日语社交礼仪中的微妙表达,并能…...

Zoom/Teams线上会议实战:从‘你静音了’到‘我掉线了’,技术人的高效沟通英语指南

技术人必备:跨国线上会议高效沟通英语实战指南 线上会议的技术挑战与沟通痛点 "Can you hear me now?"——这句在跨国线上会议中高频出现的问句,折射出技术从业者面临的沟通困境。当代码评审遇上网络延迟,当架构讨论遭遇音频断续&…...

ARM Core Tiles系统架构与开发实践指南

1. ARM Core Tiles独立使用指南:系统架构与核心原理1.1 ARM Core Tiles技术背景与应用场景ARM Core Tiles是ARM公司推出的模块化开发平台核心组件,主要用于嵌入式处理器系统的原型验证和开发。我第一次接触Core Tiles是在2006年参与一个工业控制器项目时…...

Flink 1.18.0 新手避坑指南:从第一个WordCount程序到独立部署(附常见报错解决)

Flink 1.18.0 新手避坑指南:从第一个WordCount程序到独立部署 第一次接触Flink时,那种既兴奋又忐忑的心情我至今记忆犹新。作为一款强大的分布式流处理框架,Flink 1.18.0版本带来了诸多改进,但对于新手来说,从编写第一…...

RVC语音可控性进阶:音素级对齐、时长预测、韵律建模技巧

RVC语音可控性进阶:音素级对齐、时长预测、韵律建模技巧 1. 从“能用”到“好用”:为什么需要进阶技巧? 你可能已经体验过RVC(Retrieval-based Voice Conversion)的强大,它能快速将你的声音变成另一个人的…...

深度学习图像恢复实战:基于Blurr库的统一处理框架与应用

1. 项目概述:当图像处理遇上深度学习最近在折腾一个图像处理相关的项目,需要快速实现一套从模糊图像中恢复细节的流程。说实话,这活儿听起来简单,做起来坑不少。传统的图像锐化滤镜,比如Photoshop里的USM,对…...

AIGC如何重塑软件开发流程:从工具应用到流程再造

1. 项目概述:当开源社区遇上生成式AI最近在GitHub上闲逛,又看到了Phodal(左耳朵耗子)的新项目aigc。说实话,这个名字本身就充满了想象空间——AIGC,人工智能生成内容,这几乎是过去一年里技术圈最…...

大模型代码生成质量差异分析与优化实践

1. 项目概述:大模型代码生成能力的差异研究最近在多个技术社区看到开发者讨论不同大语言模型(LLM)的代码生成质量差异,这让我想起去年参与的一个企业级代码生成项目。当时我们对比了市面上主流的7款LLM,发现虽然所有模型都能产出可运行的代码…...

别再手动传文件了!用Ansible自动化部署Kettle 8.3服务器(附Playbook)

从手动到自动化:基于Ansible的Kettle 8.3服务器高效部署指南 在数据集成与ETL领域,Pentaho Data Integration(Kettle)作为开源工具的代表,已成为企业级数据处理的标配。然而传统的手动部署方式在面对多节点、高频率更新…...

Windows 11中WSL 2安装与配置全指南

1. Windows Subsystem for Linux (WSL) 发展历程回顾Windows Subsystem for Linux(简称WSL)是微软在2016年推出的一项革命性功能,它首次让开发者能够在Windows系统上原生运行Linux二进制文件。作为一个在Windows内核上实现的兼容层&#xff0…...

Windows Cleaner:彻底释放C盘空间的智能解决方案

Windows Cleaner:彻底释放C盘空间的智能解决方案 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你的C盘是否经常亮起红色警告?系统运行越…...

ChatGPT因果推理能力评估:从事件识别到解释生成的实践与洞见

1. 项目概述与背景最近在跟进大语言模型(LLM)在特定认知任务上的表现,特别是因果推理这个领域。因果推理能力是很多高级NLP应用,比如问答、决策支持、事件预测的基石。ChatGPT这类模型在对话、创作上表现惊艳,但它真的…...

告别手忙脚乱!用立创EDA焊接辅助工具,像玩游戏一样轻松焊接你的PCB板

像玩游戏一样轻松焊接:立创EDA焊接辅助工具实战指南 焊接电路板对许多电子爱好者来说,既是创作的乐趣所在,也是容易出错的技术难点。传统焊接过程中,我们需要不断对照原理图、BOM表和实物板子,稍不留神就可能焊错元件或…...

C/C++中线程基本概念与创建详解

一、线程基本概念线程是在进程中产生的一个执行单元,是CPU调度和分配的最小单元,其在同一个进程中与其他线程并行运行,他们可以共享进程内的资源,比如内存、地址空间、打开的文件等等。线程是CPU调度和分派的基本单位,…...

如何免费解锁8大网盘全速下载:网盘直链下载助手终极指南

如何免费解锁8大网盘全速下载:网盘直链下载助手终极指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…...

F-RAM技术原理、优势与应用场景解析

1. F-RAM技术原理与核心特性解析铁电随机存取存储器(Ferroelectric Random Access Memory,简称F-RAM)是一种基于铁电材料极化特性的非易失性存储技术。与传统存储器相比,F-RAM在物理结构和工作原理上有着本质区别。1.1 铁电效应与…...

别再乱用res.send了!Express响应方法res.write、res.end、res.send、res.json的保姆级选择指南

Express响应方法深度解析:如何精准选择res.write、res.end、res.send和res.json 在Node.js开发中,Express框架的响应处理是每个开发者必须掌握的核心技能。面对不同的业务场景,如何选择合适的响应方法直接影响着应用的性能和开发效率。本文将…...

WarcraftHelper:魔兽争霸III终极性能增强与兼容性修复解决方案

WarcraftHelper:魔兽争霸III终极性能增强与兼容性修复解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper WarcraftHelper是专为魔兽争…...

ARM浮动许可证管理实战与优化指南

1. ARM浮动许可证管理基础与核心概念在嵌入式开发领域,ARM工具链的许可证管理是每个技术团队必须掌握的技能。作为从业十余年的嵌入式系统架构师,我处理过各种复杂的许可证配置场景,今天将系统性地分享ARM浮动许可证服务器的实战经验。浮动许…...

自适应剪枝高斯过程优化高维鞍点搜索效率

1. 项目背景与核心挑战在复杂系统优化领域,鞍点搜索一直是计算密集型任务中的关键瓶颈。传统的高斯过程(Gaussian Process, GP)方法虽然能有效建模非线性响应面,但在高维参数空间中面临两大痛点:一是计算复杂度随样本量…...