1. Java数学与编码工具类实战指南
作为Java开发者,我们每天都在与各种工具类打交道,但你真的了解这些基础工具类的全部潜力吗?今天我将带大家深入探索Java标准库中三个看似简单却暗藏玄机的工具类:Math数学函数、URL编码和Base64编解码。这些类在面试中经常被问及,在实际开发中也处处可见它们的身影。
我见过太多开发者对这些工具类停留在"会用"层面,却不知道如何写出健壮的测试用例,更不了解背后的设计哲学。比如Base64编码为什么会使数据膨胀1/3?URL编码为什么要区分保留字符和非保留字符?Math.random()和ThreadLocalRandom有什么区别?这些问题看似基础,却能真实反映出一个Java工程师的功底。
本文将用真实的测试案例贯穿始终,不仅告诉你这些类怎么用,还会解释为什么这样设计,以及在各种边界条件下如何正确使用它们。无论你是正在准备Java面试,还是想夯实基础,这篇文章都能给你带来新的认知。
2. Math数学函数类深度解析
2.1 基本数学运算测试
Java的Math类提供了丰富的数学计算方法,我们先从最基础的运算开始测试:
java复制@Test
public void testBasicOperations() {
// 绝对值测试
assertEquals(5, Math.abs(-5));
assertEquals(5.5, Math.abs(-5.5), 0.001);
// 四舍五入测试
assertEquals(4, Math.round(3.5));
assertEquals(4, Math.round(4.49));
// 最大值/最小值测试
assertEquals(10, Math.max(5, 10));
assertEquals(3.14, Math.min(3.14, 5.0), 0.001);
}
注意:浮点数比较必须使用delta参数,因为浮点运算存在精度问题。delta值应根据业务精度需求确定。
2.2 三角函数与对数函数测试
三角函数和对数函数在科学计算、图形处理等领域应用广泛:
java复制@Test
public void testTrigonometricAndLog() {
// 角度转弧度
double radians = Math.toRadians(30);
assertEquals(0.5236, radians, 0.0001);
// 正弦函数测试
assertEquals(0.5, Math.sin(radians), 0.0001);
// 自然对数测试
assertEquals(1.0, Math.log(Math.E), 0.0001);
// 以10为底的对数测试
assertEquals(3.0, Math.log10(1000), 0.0001);
}
2.3 随机数生成机制剖析
随机数生成是Math类的一个重要功能,但直接使用Math.random()存在一些问题:
java复制@Test
public void testRandomGeneration() {
// 生成[0,1)之间的随机数
double random = Math.random();
assertTrue(random >= 0 && random < 1);
// 生成指定范围的随机整数(不推荐方式)
int randomInt = (int)(Math.random() * 100);
assertTrue(randomInt >= 0 && randomInt < 100);
// 更专业的随机数生成方式
Random secureRandom = new SecureRandom();
int betterRandom = secureRandom.nextInt(100);
assertTrue(betterRandom >= 0 && betterRandom < 100);
}
实际开发中建议使用ThreadLocalRandom(单线程)或SecureRandom(安全敏感场景)替代Math.random(),因为它们有更好的性能和随机性。
3. URL编码类的正确使用姿势
3.1 基本编码解码测试
URL编码用于处理URL中的特殊字符,我们先看基本用法:
java复制@Test
public void testBasicURLEncoding() throws UnsupportedEncodingException {
String original = "搜索 查询?q=java&version=8";
// 使用UTF-8编码
String encoded = URLEncoder.encode(original, "UTF-8");
assertEquals("%E6%90%9C%E7%B4%A2+%E6%9F%A5%E8%AF%A2%3Fq%3Djava%26version%3D8", encoded);
// 解码测试
String decoded = URLDecoder.decode(encoded, "UTF-8");
assertEquals(original, decoded);
}
3.2 保留字符处理策略
URL编码会区分保留字符和非保留字符,保留字符不会被编码:
java复制@Test
public void testReservedCharacters() throws UnsupportedEncodingException {
// 保留字符示例:- _ . ! ~ * ' ( )
String reserved = "-_.!~*'()";
String encoded = URLEncoder.encode(reserved, "UTF-8");
assertEquals(reserved, encoded); // 保留字符不会被编码
// 非保留字符会被编码
String nonReserved = "#$&+,/:;=?@[]";
String encodedNonReserved = URLEncoder.encode(nonReserved, "UTF-8");
assertNotEquals(nonReserved, encodedNonReserved);
}
3.3 编码陷阱与最佳实践
URL编码在实际使用中有几个常见陷阱需要注意:
java复制@Test
public void testURLEncodingPitfalls() throws UnsupportedEncodingException {
// 陷阱1:空格编码为+号,但某些场景需要%20
String withSpace = "hello world";
String encoded = URLEncoder.encode(withSpace, "UTF-8");
assertEquals("hello+world", encoded);
// 如果需要%20而不是+号,可以替换
String encodedWithPercent20 = encoded.replace("+", "%20");
assertEquals("hello%20world", encodedWithPercent20);
// 陷阱2:多次编码问题
String doubleEncoded = URLEncoder.encode(encoded, "UTF-8");
assertNotEquals(encoded, doubleEncoded);
// 陷阱3:不同字符集编码结果不同
String chinese = "中文";
String utf8Encoded = URLEncoder.encode(chinese, "UTF-8");
String gbkEncoded = URLEncoder.encode(chinese, "GBK");
assertNotEquals(utf8Encoded, gbkEncoded);
}
最佳实践:始终明确指定字符集(推荐UTF-8),避免多次编码,根据接收方要求处理空格编码方式。
4. Base64编解码全面指南
4.1 三种Base64编码方式对比
Java 8以后提供了三种Base64编码器,各有适用场景:
java复制@Test
public void testBase64Variants() {
String original = "Java Base64测试123!@#";
byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8);
// 基本编码器(会添加换行)
String basicEncoded = Base64.getEncoder().encodeToString(originalBytes);
assertTrue(basicEncoded.contains("\n"));
// URL安全的编码器(替换+/为-_)
String urlEncoded = Base64.getUrlEncoder().encodeToString(originalBytes);
assertFalse(urlEncoded.contains("+") || urlEncoded.contains("/"));
// MIME编码器(每76字符换行)
String mimeEncoded = Base64.getMimeEncoder().encodeToString(originalBytes);
assertTrue(mimeEncoded.contains("\r\n"));
// 无换行符的编码
String noWrapEncoded = Base64.getEncoder().withoutPadding().encodeToString(originalBytes);
assertFalse(noWrapEncoded.contains("\n"));
}
4.2 编码长度与性能考量
Base64编码会使数据大小增加约33%,这在处理大文件时需要特别注意:
java复制@Test
public void testBase64SizeIncrease() {
// 原始数据
byte[] original = new byte[300]; // 300字节
Arrays.fill(original, (byte)1);
// 编码后
String encoded = Base64.getEncoder().encodeToString(original);
int encodedLength = encoded.length();
// 计算膨胀率
double expansionRatio = (double)encodedLength / original.length;
assertEquals(1.3333, expansionRatio, 0.01); // 约33%的增长
// 大文件编码性能测试
byte[] largeData = new byte[10 * 1024 * 1024]; // 10MB
Arrays.fill(largeData, (byte)1);
long startTime = System.currentTimeMillis();
Base64.getEncoder().encodeToString(largeData);
long duration = System.currentTimeMillis() - startTime;
assertTrue(duration < 1000); // 10MB数据编码应在1秒内完成
}
4.3 实际应用场景测试
Base64在多种场景下都有应用,下面是几个典型用例:
java复制@Test
public void testBase64UseCases() throws IOException {
// 场景1:图片转Base64
byte[] imageBytes = Files.readAllBytes(Paths.get("test.png"));
String imageBase64 = Base64.getEncoder().encodeToString(imageBytes);
assertTrue(imageBase64.startsWith("iVBOR"));
// 场景2:Basic认证
String credentials = "username:password";
String authHeader = "Basic " + Base64.getEncoder()
.encodeToString(credentials.getBytes());
assertTrue(authHeader.startsWith("Basic dXNlcm5hbWU6cGFzc3dvcmQ="));
// 场景3:URL传输二进制数据
byte[] binaryData = {0x01, 0x02, 0x7F, (byte)0xFF};
String urlSafe = Base64.getUrlEncoder().encodeToString(binaryData);
assertFalse(urlSafe.contains("+") || urlSafe.contains("/"));
}
在处理图片等二进制数据时,内存消耗会显著增加,建议使用流式处理API(Base64.getEncoder().wrap(outputStream))来避免内存溢出。
5. 综合测试与边界条件验证
5.1 异常情况处理测试
健壮的代码必须能处理各种边界和异常情况:
java复制@Test(expected = NullPointerException.class)
public void testNullInput() throws UnsupportedEncodingException {
// Math类处理null
Math.abs(null); // 编译错误
// URL编码处理null
URLEncoder.encode(null, "UTF-8");
}
@Test
public void testEmptyString() throws UnsupportedEncodingException {
// 空字符串编码
assertEquals("", URLEncoder.encode("", "UTF-8"));
assertEquals("", Base64.getEncoder().encodeToString(new byte[0]));
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidBase64() {
// 无效Base64字符串解码
Base64.getDecoder().decode("这不是有效的Base64!");
}
5.2 性能对比测试
不同实现方式的性能差异可能很大:
java复制@Test
public void testPerformanceComparison() {
byte[] data = new byte[1_000_000]; // 1MB数据
new Random().nextBytes(data);
// 测试1:Base64编码性能
long base64Start = System.nanoTime();
String base64Encoded = Base64.getEncoder().encodeToString(data);
long base64Duration = System.nanoTime() - base64Start;
// 测试2:URL编码性能(仅测试前100字节)
long urlStart = System.nanoTime();
String urlEncoded = URLEncoder.encode(new String(data, 0, 100), StandardCharsets.UTF_8);
long urlDuration = System.nanoTime() - urlStart;
// Base64处理大数据量更高效
assertTrue(base64Duration < TimeUnit.SECONDS.toNanos(1));
assertTrue(urlDuration < base64Duration); // URL编码小数据更快
}
5.3 线程安全性验证
这些工具类的线程安全性对并发应用至关重要:
java复制@Test
public void testThreadSafety() throws InterruptedException {
int threadCount = 10;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
CountDownLatch latch = new CountDownLatch(threadCount);
AtomicInteger mathSuccess = new AtomicInteger();
AtomicInteger base64Success = new AtomicInteger();
for (int i = 0; i < threadCount; i++) {
executor.submit(() -> {
try {
// 并发调用Math方法
double result = Math.sin(Math.random());
assertTrue(result >= -1 && result <= 1);
mathSuccess.incrementAndGet();
// 并发Base64编码
byte[] data = new byte[100];
new Random().nextBytes(data);
String encoded = Base64.getEncoder().encodeToString(data);
assertEquals(136, encoded.length()); // 100字节编码后为136字符
base64Success.incrementAndGet();
} finally {
latch.countDown();
}
});
}
latch.await(5, TimeUnit.SECONDS);
assertEquals(threadCount, mathSuccess.get());
assertEquals(threadCount, base64Success.get());
}
6. 测试工具类设计模式
6.1 测试工具方法封装
为了提高测试代码的复用性,我们可以封装一些工具方法:
java复制public class EncodingTestUtils {
public static String encodeToBase64(String input) {
return Base64.getEncoder().encodeToString(input.getBytes(StandardCharsets.UTF_8));
}
public static String decodeFromBase64(String input) {
return new String(Base64.getDecoder().decode(input), StandardCharsets.UTF_8);
}
public static double calculateStandardDeviation(double[] values) {
double avg = Arrays.stream(values).average().orElse(0);
double variance = Arrays.stream(values)
.map(v -> Math.pow(v - avg, 2))
.average().orElse(0);
return Math.sqrt(variance);
}
}
@Test
public void testUtilityMethods() {
// 测试封装的Base64工具方法
String original = "测试工具方法";
String encoded = EncodingTestUtils.encodeToBase64(original);
String decoded = EncodingTestUtils.decodeFromBase64(encoded);
assertEquals(original, decoded);
// 测试标准差计算
double[] values = {1, 2, 3, 4, 5};
double stdDev = EncodingTestUtils.calculateStandardDeviation(values);
assertEquals(1.4142, stdDev, 0.0001);
}
6.2 参数化测试实践
使用JUnit 5的参数化测试可以更高效地测试多种情况:
java复制@ParameterizedTest
@ValueSource(strings = {"hello", "12345", "特殊字符!@#$", "中文测试"})
public void testBase64RoundTrip(String input) {
String encoded = Base64.getEncoder().encodeToString(input.getBytes());
String decoded = new String(Base64.getDecoder().decode(encoded));
assertEquals(input, decoded);
}
@ParameterizedTest
@CsvSource({
"0, 1.0",
"30, 0.5",
"45, 0.7071",
"90, 1.0"
})
public void testSinDegrees(int degrees, double expected) {
double radians = Math.toRadians(degrees);
assertEquals(expected, Math.sin(radians), 0.0001);
}
6.3 测试覆盖率提升技巧
确保测试覆盖各种边界条件:
java复制@Test
public void testCoverage() {
// Math类边界值测试
assertEquals(Double.POSITIVE_INFINITY, Math.log(0), 0.0);
assertEquals(Double.NaN, Math.sqrt(-1), 0.0);
// Base64边界测试
byte[] oneByte = {0x41}; // 'A'
String oneByteEncoded = Base64.getEncoder().encodeToString(oneByte);
assertEquals("QQ==", oneByteEncoded);
byte[] twoBytes = {0x41, 0x42}; // 'AB'
String twoBytesEncoded = Base64.getEncoder().encodeToString(twoBytes);
assertEquals("QUI=", twoBytesEncoded);
// URL编码边界测试
String allAscii = IntStream.range(0, 128)
.mapToObj(i -> String.valueOf((char)i))
.collect(Collectors.joining());
String encodedAllAscii = URLEncoder.encode(allAscii, StandardCharsets.UTF_8);
assertTrue(encodedAllAscii.length() > allAscii.length());
}
7. 实际项目集成经验
7.1 配置文件中的Base64处理
在实际项目中,我们经常需要在配置文件中存储Base64编码的数据:
java复制@Test
public void testConfigFileIntegration() {
// 模拟从配置文件读取Base64编码的值
String base64PasswordInConfig = "c2VjcmV0MTIz"; // "secret123"的Base64编码
// 解码使用
String actualPassword = new String(
Base64.getDecoder().decode(base64PasswordInConfig),
StandardCharsets.UTF_8
);
assertEquals("secret123", actualPassword);
// 更安全的做法是使用加密而非Base64
// Base64不是加密,只是编码,敏感数据应该加密存储
}
7.2 API开发中的URL编码实践
在Web API开发中正确处理URL编码至关重要:
java复制@Test
public void testAPIRequestHandling() throws UnsupportedEncodingException {
// 模拟接收编码后的查询参数
String encodedQuery = "q=%E4%B8%AD%E6%96%87%E6%90%9C%E7%B4%A2&page=1";
// 解码处理
String decodedQuery = URLDecoder.decode(encodedQuery, "UTF-8");
assertEquals("q=中文搜索&page=1", decodedQuery);
// 模拟构建URL
String baseUrl = "https://example.com/search";
String query = "价格>=100";
String fullUrl = baseUrl + "?q=" + URLEncoder.encode(query, "UTF-8");
assertEquals("https://example.com/search?q=%E4%BB%B7%E6%A0%BC%3E%3D100", fullUrl);
}
7.3 数学计算在业务逻辑中的应用
业务逻辑中经常需要各种数学计算:
java复制@Test
public void testBusinessCalculations() {
// 金融计算 - 复利
double principal = 10000;
double rate = 0.05;
int years = 5;
double amount = principal * Math.pow(1 + rate, years);
assertEquals(12762.82, amount, 0.01);
// 几何计算 - 两点间距离
double x1 = 3, y1 = 4;
double x2 = 0, y2 = 0;
double distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
assertEquals(5.0, distance, 0.001);
// 随机分配 - 公平性验证
int[] buckets = new int[10];
int trials = 1000000;
for (int i = 0; i < trials; i++) {
int bucket = (int)(Math.random() * buckets.length);
buckets[bucket]++;
}
double expected = trials / (double)buckets.length;
double stdDev = EncodingTestUtils.calculateStandardDeviation(
Arrays.stream(buckets).asDoubleStream().toArray());
assertTrue(stdDev < expected * 0.01); // 标准差应小于1%的期望值
}
8. 高级技巧与最佳实践
8.1 Base64流式处理大文件
处理大文件时应避免内存溢出:
java复制@Test
public void testStreamingBase64() throws IOException {
// 创建临时大文件(10MB)
Path tempFile = Files.createTempFile("large", ".bin");
byte[] randomData = new byte[10 * 1024 * 1024]; // 10MB
new Random().nextBytes(randomData);
Files.write(tempFile, randomData);
// 传统方式(可能内存溢出)
try {
byte[] allBytes = Files.readAllBytes(tempFile);
String encoded = Base64.getEncoder().encodeToString(allBytes);
assertNotNull(encoded);
} catch (OutOfMemoryError e) {
fail("可能导致内存溢出");
}
// 流式处理方式
try (InputStream in = Files.newInputStream(tempFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream b64Out = Base64.getEncoder().wrap(out)) {
byte[] buffer = new byte[4096];
int len;
while ((len = in.read(buffer)) > 0) {
b64Out.write(buffer, 0, len);
}
String streamEncoded = out.toString("UTF-8");
assertNotNull(streamEncoded);
}
Files.delete(tempFile);
}
8.2 自定义URL编码规则
有时需要自定义编码规则以满足特定需求:
java复制@Test
public void testCustomURLEncoding() {
// 自定义编码器,不编码某些特殊字符
BiFunction<String, Charset, String> customEncoder = (s, charset) -> {
try {
String encoded = URLEncoder.encode(s, charset.name());
// 还原我们不需要编码的字符
encoded = encoded.replace("%3A", ":")
.replace("%2F", "/")
.replace("%3F", "?");
return encoded;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
};
String url = "https://example.com/path?query=value";
String encoded = customEncoder.apply(url, StandardCharsets.UTF_8);
assertEquals("https://example.com/path?query=value", encoded);
}
8.3 数学计算的精度控制
金融等场景需要精确的数值计算:
java复制@Test
public void testPrecisionControl() {
// 浮点数精度问题
double sum = 0.0;
for (int i = 0; i < 10; i++) {
sum += 0.1;
}
assertNotEquals(1.0, sum); // 实际是0.9999999999999999
// 使用BigDecimal解决精度问题
BigDecimal decimalSum = BigDecimal.ZERO;
BigDecimal tenth = new BigDecimal("0.1");
for (int i = 0; i < 10; i++) {
decimalSum = decimalSum.add(tenth);
}
assertEquals(0, new BigDecimal("1.0").compareTo(decimalSum));
// 三角函数精度控制
double preciseSin = Math.sin(Math.toRadians(30));
assertEquals(0.5, preciseSin, 1e-15); // 非常高的精度要求
}
9. 常见问题排查手册
9.1 Base64编码问题排查
java复制@Test
public void troubleshootBase64Issues() {
// 问题1:编码结果末尾有=或==
// 这是正常的填充字符,可以使用withoutPadding()去掉
String withPadding = Base64.getEncoder().encodeToString("a".getBytes());
assertEquals("YQ==", withPadding);
String withoutPadding = Base64.getEncoder().withoutPadding().encodeToString("a".getBytes());
assertEquals("YQ", withoutPadding);
// 问题2:编码字符串包含换行
// 使用withoutPadding()或getMimeEncoder()控制换行
String withNewlines = Base64.getMimeEncoder().encodeToString(new byte[100]);
assertTrue(withNewlines.contains("\r\n"));
// 问题3:URL不安全的+和/字符
// 使用getUrlEncoder()获取URL安全版本
String urlUnsafe = Base64.getEncoder().encodeToString(new byte[]{(byte)0xFF});
assertTrue(urlUnsafe.contains("+"));
String urlSafe = Base64.getUrlEncoder().encodeToString(new byte[]{(byte)0xFF});
assertTrue(urlSafe.contains("-"));
}
9.2 URL编码乱码问题排查
java复制@Test
public void troubleshootURLEncodingIssues() throws UnsupportedEncodingException {
// 问题1:中文乱码
// 确保编码解码使用相同的字符集
String chinese = "中文";
String wrongEncoded = URLEncoder.encode(chinese, "ISO-8859-1");
String wrongDecoded = URLDecoder.decode(wrongEncoded, "ISO-8859-1");
assertEquals(chinese, wrongDecoded); // 会失败,因为ISO-8859-1不支持中文
// 正确做法:始终使用UTF-8
String correctEncoded = URLEncoder.encode(chinese, "UTF-8");
String correctDecoded = URLDecoder.decode(correctEncoded, "UTF-8");
assertEquals(chinese, correctDecoded);
// 问题2:+号被解码为空格
// 某些场景需要保留+号,可以先替换为%2B
String withPlus = "1+1=2";
String encoded = URLEncoder.encode(withPlus, "UTF-8").replace("+", "%2B");
assertEquals("1%2B1%3D2", encoded);
}
9.3 数学计算精度问题排查
java复制@Test
public void troubleshootMathPrecisionIssues() {
// 问题1:浮点数比较
// 错误方式:直接使用==
double result = 0.1 + 0.2;
assertFalse(result == 0.3); // 实际上0.30000000000000004
// 正确方式:使用delta比较
assertEquals(0.3, result, 0.0001);
// 问题2:大数计算溢出
// 错误方式:使用基本类型
int bigNum = Integer.MAX_VALUE;
assertThrows(ArithmeticException.class, () -> Math.addExact(bigNum, 1));
// 正确方式:使用long或BigInteger
long biggerNum = (long)Integer.MAX_VALUE + 1;
assertEquals(2147483648L, biggerNum);
// 问题3:三角函数角度/弧度混淆
// 错误方式:直接传入角度
double wrongSin = Math.sin(30); // 30弧度不是30度
assertNotEquals(0.5, wrongSin, 0.001);
// 正确方式:转换为弧度
double correctSin = Math.sin(Math.toRadians(30));
assertEquals(0.5, correctSin, 0.001);
}
10. 测试代码优化与维护
10.1 测试数据工厂模式
使用工厂方法创建测试数据可以提高测试可维护性:
java复制public class TestDataFactory {
public static byte[] randomBytes(int length) {
byte[] bytes = new byte[length];
new Random().nextBytes(bytes);
return bytes;
}
public static String randomString(int length) {
int leftLimit = 48; // '0'
int rightLimit = 122; // 'z'
return new Random().ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(length)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
}
@Test
public void testWithGeneratedData() {
// 使用工厂方法生成测试数据
byte[] randomData = TestDataFactory.randomBytes(1024);
String encoded = Base64.getEncoder().encodeToString(randomData);
byte[] decoded = Base64.getDecoder().decode(encoded);
assertArrayEquals(randomData, decoded);
String randomString = TestDataFactory.randomString(100);
String urlEncoded = URLEncoder.encode(randomString, StandardCharsets.UTF_8);
String urlDecoded = URLDecoder.decode(urlEncoded, StandardCharsets.UTF_8);
assertEquals(randomString, urlDecoded);
}
10.2 测试资源清理策略
妥善管理测试资源可以避免副作用:
java复制@Test
public void testWithTemporaryResources() throws IOException {
// 创建临时文件
Path tempFile = Files.createTempFile("test", ".txt");
try {
// 写入测试数据
String content = "临时文件内容";
Files.write(tempFile, content.getBytes());
// 测试Base64文件编码
byte[] fileBytes = Files.readAllBytes(tempFile);
String encoded = Base64.getEncoder().encodeToString(fileBytes);
assertEquals("5o6o5aSN5paH5Lu2", encoded); // "临时文件内容"的Base64
} finally {
// 确保清理临时文件
Files.deleteIfExists(tempFile);
}
}
10.3 性能测试框架集成
对于性能敏感的代码,可以集成JMH进行微基准测试:
java复制/*
// 需要单独运行的JMH基准测试
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Benchmark)
public class EncodingBenchmark {
private byte[] testData;
@Setup
public void setup() {
testData = new byte[1024];
new Random().nextBytes(testData);
}
@Benchmark
public String base64Encode() {
return Base64.getEncoder().encodeToString(testData);
}
@Benchmark
public String urlEncode() {
return URLEncoder.encode(new String(testData), StandardCharsets.UTF_8);
}
}
*/
@Test
public void testPerformanceSensitiveCode() {
// 简单性能验证(完整基准测试应使用JMH)
byte[] data = new byte[1024];
new Random().nextBytes(data);
long base64Start = System.nanoTime();
Base64.getEncoder().encodeToString(data);
long base64Duration = System.nanoTime() - base64Start;
long urlStart = System.nanoTime();
URLEncoder.encode(new String(data), StandardCharsets.UTF_8);
long urlDuration = System.nanoTime() - urlStart;
// Base64通常比URL编码快
assertTrue(base64Duration < urlDuration);
}
