Java日常探秘-从小疑问到实践智慧的编程之旅(1)

2024-06-24 04:12

本文主要是介绍Java日常探秘-从小疑问到实践智慧的编程之旅(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、Git中回滚操作的方式
  • 二、加密为第三方服务,需要rpc,怎么提高效率
  • 三、加解密需求,逻辑能够尽量收敛
  • 四、加解密优化
  • 五、加解密的rpc失败了处理机制
  • 六、优化MySQL查询
  • 总结


前言

所有分享的内容源于日常思考和实践,探讨Java编程中的小知识点和实用场景,加深自己对编程技巧和理解Java深层次的原理,期待发现妙招和解决实际问题的新思路。


一、Git中回滚操作的方式

在实际工作场景中,我们会遇到提交了不想提交的代码又或者是代码有问题需要紧急回滚的场景,接下来分享几种Git回滚代码的操作。

reset current branch to here、revert commit 和 undo commit 都是 Git 中回滚操作的方式,但它们之间有以下区别:

  1. reset current branch to here该操作会将当前分支重置到指定的 commit,之后的 commit 记录将被删除。这意味着,如果你已经将这些 commit 推送到远程仓库,那么你需要使用强制推送来覆盖远程仓库中的 commit 记录。因此,该操作不适用于已经推送到远程仓库的 commit 记录。
  2. revert commit:该操作会创建一个新的 commit 记录,用于撤销指定的 commit 记录。这意味着,你可以将该操作应用于已经推送到远程仓库的 commit 记录,而不需要强制推送。但是,该操作会保留原始 commit 记录,因此你需要在 commit 记录中添加一些注释来说明你为什么要进行 revert 操作。
  3. undo commit:该操作会撤销最近的 commit 记录,但是不会删除该 commit 记录。这意味着,你可以在 commit 记录中添加一些注释来说明你为什么要进行 undo 操作。但是,该操作只适用于本地仓库,如果你已经将 commit 记录推送到远程仓库,那么你需要使用 revert 或 reset 操作来回滚 commit 记录。

二、加密为第三方服务,需要rpc,怎么提高效率

什么是RPC:RPC是指远程过程调用,也就是两个服务器A和B,A想调用B服务器上通过的接口,但是不在一个内存空间不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

加密为第三方服务,需要rpc,怎么提高效率?

  1. 批量存储:将多个需要加密的数据进行批量存储,减少RPC调用的次数。可以将需要加密的数据按照一定的规则进行分组,然后一次性发送给第三方服务进行加密,最后再将加密后的数据一次性存储到数据库中。
  2. 异步调用:将RPC调用改为异步调用,不需要等待加密结果返回再进行存储操作。可以使用JAVA中的异步编程模型,例如使用CompletableFuture或者使用消息队列等方式,将加密请求发送给第三方服务后立即返回,然后在加密结果返回后再进行存储操作。
  3. 缓存加密结果:将加密结果缓存起来,避免重复的RPC调用。可以使用缓存技术,例如使用Redis等内存数据库,将加密结果存储在缓存中,下次需要加密相同的数据时,先从缓存中获取加密结果,如果缓存中不存在,则再进行RPC调用。
  4. 优化网络通信:优化网络通信的性能,减少RPC调用的延迟。可以使用高性能的网络框架,例如Netty,优化网络通信的效率,减少网络传输的时间。
  5. 使用本地加密:如果可能的话,可以考虑使用本地加密算法,避免RPC调用。可以使用JAVA中提供的加密算法库,例如Java Cryptography Architecture (JCA),在本地进行加密操作,然后再进行存储。

三、加解密需求,逻辑能够尽量收敛

JAVA需求上需要对部分字段加密,读取时解密,又希望这个逻辑能够尽量收敛,避免业务层代码遍地都是加解密,同时又能收敛和管控加密的算法,强度,密钥。

  1. 首先,选择合适的加密算法和密钥管理方案。Java提供了丰富的加密算法和密钥管理类,例如AES、DES、RSA等。根据需求和安全性要求,选择适合的算法和密钥长度。

  2. 创建一个加密工具类,封装加密和解密的逻辑。该工具类可以包含以下方法,在业务层代码中,使用加密工具类对需要加密的字段进行加密和解密操作。可以将加密逻辑封装在业务层的服务类中,避免代码重复:
    2.1 生成密钥对:使用密钥管理类生成公钥和私钥对,用于加密和解密。
    2.2 加密方法:接收明文数据和密钥,使用选择的加密算法对数据进行加密,并返回密文。
    2.3 解密方法:接收密文数据和密钥,使用选择的解密算法对数据进行解密,并返回明文。

  3. 对于加密算法、密钥长度和密钥管理的收敛和管控,可以在加密工具类中进行配置和管理。可以将算法和密钥长度作为参数传入加密方法中,或者通过配置文件进行管理。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;public class EncryptionUtils {private static final String ENCRYPTION_ALGORITHM = "AES";public static KeyPair generateKeyPair() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);return keyPairGenerator.generateKeyPair();}public static byte[] encrypt(byte[] data, SecretKey secretKey) throws Exception {Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, secretKey);return cipher.doFinal(data);}public static byte[] decrypt(byte[] encryptedData, SecretKey secretKey) throws Exception {Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, secretKey);return cipher.doFinal(encryptedData);}
}// 使用示例
public class Main {public static void main(String[] args) throws Exception {// 生成密钥对KeyPair keyPair = EncryptionUtils.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 加密数据String plaintext = "Hello, World!";byte[] encryptedData = EncryptionUtils.encrypt(plaintext.getBytes(), publicKey);// 解密数据byte[] decryptedData = EncryptionUtils.decrypt(encryptedData, privateKey);String decryptedText = new String(decryptedData);System.out.println("Plaintext: " + plaintext);System.out.println("Encrypted data: " + Arrays.toString(encryptedData));System.out.println("Decrypted text: " + decryptedText);}
}

四、加解密优化

在Java代码中,如果有部分获取数据的请求不需要被加密的字段,只需要其余几列,可以通过以下方式优化加解密:

1.首先,确定哪些字段需要加密,哪些字段不需要加密。将需要加密的字段标记为加密字段。
2.在获取数据的请求中,先查询出所有需要的字段,包括加密字段和非加密字段。
3.对于非加密字段,直接返回给客户端,无需进行加解密操作。
4.对于加密字段,使用加密算法对其进行加密操作。
5.将加密后的字段与非加密字段合并,组成最终的返回结果。

通过以上优化,可以避免对不需要加密的字段进行加解密操作,提高代码的执行效率。

// 查询数据
String sql = "SELECT column1, column2, column3 FROM table_name WHERE condition";
ResultSet rs = statement.executeQuery(sql);// 遍历结果集
while (rs.next()) {// 获取非加密字段String column1 = rs.getString("column1");String column3 = rs.getString("column3");// 获取加密字段String encryptedColumn2 = rs.getString("column2");// 对加密字段进行解密操作String decryptedColumn2 = decrypt(encryptedColumn2);// 组合最终结果String result = column1 + ", " + decryptedColumn2 + ", " + column3;// 返回结果给客户端// ...
}// 关闭结果集和连接
rs.close();
statement.close();
connection.close();

五、加解密的rpc失败了处理机制

Java RPC框架熔断降级机制原理,当加解密的RPC临时失败时,通常会选择进行降级而不是直接报错。降级是指在服务不可用或不稳定的情况下,提供一种备用的功能或数据,以保证系统的可用性和稳定性。

降级的方式可以根据具体情况而定,常见的降级策略包括:

  1. 返回默认值:当RPC调用失败时,可以返回一个默认的加解密结果,例如返回空字符串或者默认的加解密结果。
  2. 返回缓存数据:如果之前的加解密结果已经缓存在本地或者其他地方,可以直接返回缓存的结果,避免再次进行RPC调用。
  3. 返回错误码或异常信息:可以返回一个特定的错误码或异常信息,提示用户当前服务不可用,同时记录日志以便后续排查问题。
  4. 通过降级策略:可以保证系统在RPC临时失败时仍然能够正常运行,提高系统的可用性和稳定性。

六、优化MySQL查询

用mysql查询太慢了,希望改成某种序列化KV,过渡期不能停服,要双写同时又要保证数据一致性要怎么做?

可以考虑使用TDSQL作为替代方案。TDSQL是腾讯云数据库的一种金融级分布式产品,它支持多引擎的统一标准化服务,包括MySQL和PostgreSQL等开源生态数据库。TDSQL提供了高可用性和高性能的特性,可以满足你的需求。

为了实现过渡期不停服,并且保证数据一致性,你可以采用以下步骤:

  1. TDSQL实例:在腾讯云控制台上创建一个TDSQL实例,选择适合你的业务需求的引擎类型(如MySQL或PostgreSQL)。
  2. 数据迁移:将现有的MySQL数据库中的数据迁移到TDSQL实例中。你可以使用腾讯云提供的数据迁移工具或者自行编写脚本来完成数据迁移。
  3. 双写机制:在过渡期间,你可以使用双写机制来保证数据的一致性。具体做法是,在每次写入操作时,同时将数据写入MySQL和TDSQL实例中。这样可以确保数据在两个数据库中保持一致。
  4. 数据同步:为了保证数据的实时同步,你可以使用数据库的主从复制功能。将MySQL设置为主数据库,TDSQL实例设置为从数据库,通过主从复制机制将数据实时同步到TDSQL实例中。
  5. 测试和验证:在完成数据迁移和双写机制的配置后,进行测试和验证,确保数据在两个数据库中的一致性和可用性。

需要注意的是,在过渡期间,你需要监控和管理两个数据库的运行状态,确保数据的一致性和可用性。一旦过渡期结束,你可以停止对MySQL数据库的写入操作,只使用TDSQL实例作为主数据库。

从mysql查询改成某种序列化KV查询,但KV可能挂,能临时用mysql降级先存着,KV恢复时再写回来,能保证数据不丢失吗?
答:通过将查询方式从mysql改为某种序列化KV查询,并且在KV挂掉时临时使用mysql降级存储,可以一定程度上保证数据不丢失。当KV挂掉时,可以将数据先写入mysql,等KV恢复后再将数据写回KV。这样做的好处是即使KV挂掉,数据仍然可以通过mysql进行查询和存储,避免了数据的丢失。当KV恢复后,再将mysql中的数据写回KV,保证数据的完整性。

然而,需要注意的是,这种降级存储方案并不能完全保证数据不丢失。在KV挂掉后,如果mysql也发生故障或者数据丢失,那么数据就无法恢复了。因此,在实际应用中,需要对mysql进行备份和故障恢复的措施,以确保数据的安全性和可靠性。


总结

本篇文章主要介绍了Git代码的回滚的几种方法以及加解密的几种常见优化方法以及异常处理机制,最后介绍了优化mysql查询时如何保证数据一致性以及预防数据丢失的情况,期待给读者提供解决实际问题的新思路。


这篇关于Java日常探秘-从小疑问到实践智慧的编程之旅(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089140

相关文章

Java StringBuilder 实现原理全攻略

《JavaStringBuilder实现原理全攻略》StringBuilder是Java提供的可变字符序列类,位于java.lang包中,专门用于高效处理字符串的拼接和修改操作,本文给大家介绍Ja... 目录一、StringBuilder 基本概述核心特性二、StringBuilder 核心实现2.1 内部

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

SpringBoot AspectJ切面配合自定义注解实现权限校验的示例详解

《SpringBootAspectJ切面配合自定义注解实现权限校验的示例详解》本文章介绍了如何通过创建自定义的权限校验注解,配合AspectJ切面拦截注解实现权限校验,本文结合实例代码给大家介绍的非... 目录1. 创建权限校验注解2. 创建ASPectJ切面拦截注解校验权限3. 用法示例A. 参考文章本文

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使

Java Stream流与使用操作指南

《JavaStream流与使用操作指南》Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库,本文给大家介绍JavaStream流与使用... 目录一、什么是stream流二、创建stream流1.单列集合创建stream流2.双列集合创建str

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具