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实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2