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


前言

所有分享的内容源于日常思考和实践,探讨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查询时如何保证数据一致性以及预防数据丢失的情况,期待给读者提供解决实际问题的新思路。


  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JinziH Never Give Up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值