# 《高性能脱敏组件》测试验证-第02节:高性能脱敏组件JMH基准性能测试

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:对高性能脱敏组件进行JMH基准性能测试,从全局角度掌握高性能脱敏组件对敏感信息和隐私数据脱敏的核心设计思路和设计方法。重点掌握通用中间件项目的设计思路和设计方法,并能够将其灵活应用到自身实际项目中。

大家好,我是冰河~~

截止到目前,我们已经实现了高性能脱敏组件最基础与最核心的功能,能够对绝大部分场景下的敏感信息和隐私数据进行脱敏操作,以避免这些数据被泄露。并且在实现高性能脱敏组件时,提供了三种对接方式:通用方法方式、注解接入方式和日志接入方法。并且在测试验证篇章,对高性能脱敏组件提供的三种接入方式进行了单元测试。

# 一、前言

在需求设计篇章,我们梳理了为何学习高性能脱敏组件,阐述了高性能脱敏组件的目标与挑战,对设计高性能脱敏组件面对的挑战给出了详细的应对方案,并且从功能性需求和非功能性需求等方面详细梳理了高性能脱敏组件的需求。

在架构设计篇章,详细阐述了高性能脱敏组件的方案目标、技术选型和总体架构设计。并且对高性能脱敏组件的通用化落地方案进行了简单的说明。

在脱敏设计篇章,我们已经对高性能脱敏组件进行了编码设计和实现,目前,已经对注解、接口与顶层抽象类进行了设计和实现,并且对高性能脱敏组件的通用脱敏方法和注解的通用解析逻辑以及内置的各种常见数据脱敏器进行了设计和实现,同时,基于高性能脱敏组件的通用脱敏方法对日志脱敏进行了拓展设计和实现。

在测试验证篇章,已经对高性能脱敏组件实现的功能进行了单元测试。接下来,就对高性能脱敏组件进行JMH基准性能测试。

# 二、本节诉求

对高性能脱敏组件进行JMH基准性能测试,从全局角度掌握高性能脱敏组件对敏感信息和隐私数据脱敏的核心设计思路和设计方法。重点掌握通用中间件项目的设计思路和设计方法,并能够将其灵活应用到自身实际项目中。

# 三、编码实现

本节,在《第01节:高性能脱敏数据组件单元测试场景验证 (opens new window)》的基础上,进一步对高性能脱敏组件进行JMH基准性能测试。实现基准性能测试的类比较简单,创建一个ShieldJMHTest类即可。

源码详见:io.binghe.framework.shield.test.jmh.ShieldJMHTest。

@BenchmarkMode(Mode.All)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@Threads(8)
public class ShieldJMHTest {

    private static TestAClass aClass;
    private static TestBClass bClass;

    static {
        aClass = new TestAClass();
        aClass.setA("AAAAAAAAAAAAAAAAAAAAAAAA");
        aClass.setB("BBBBBBBBBBBBBBBBBBBBBBBB");
        aClass.setBint(1234567890);
        aClass.setBlong(1234567890L);
        aClass.setC("CCCCCCCCCCCCCCCCCCCCCCCC");

        TestABClass abClass = new TestABClass();
        abClass.setA("AAAAAAAAAAAAAAAAAAAAAAAAA");
        aClass.setTestABClass(abClass);

        bClass = new TestBClass();
        bClass.setA("AAAAAAAAAAAAAAAAAAAAAAAA");
        bClass.setB("BBBBBBBBBBBBBBBBBBBBBBBB");
        bClass.setBint(1234567890);
        bClass.setBlong(1234567890L);
        bClass.setC("CCCCCCCCCCCCCCCCCCCCCCCC");

    }

    @Param(value = {"100", "10000", "1000000"})
    private int length;

    @Benchmark
    public void shieldUtilsTest(){
        for (int i = 0; i < length; i++) {
            ReflectUtils.reflectToLogStringByFields(aClass);
        }
    }

    @Benchmark
    public void toStringTest(){
        for (int i = 0; i < length; i++) {
            aClass.toString();
        }
    }

    @Benchmark
    public void jsonTest(){
        for (int i = 0; i < length; i++) {
            JSON.toJSONString(aClass);
        }
    }

    @Benchmark
    public void noShieldUtilsTest(){
        for (int i = 0; i < length; i++) {
            ReflectUtils.reflectToLogStringByFields(bClass);
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options opts = new OptionsBuilder().include(ShieldJMHTest.class.getSimpleName()).resultFormat(ResultFormatType.JSON).build();
        new Runner(opts).run();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

可以看到,ShieldJMHTest类主要是通过JMH对高性能脱敏组件进行基准测试的类。有关JMH基准测试的知识,后续我会单开一个专栏深入介绍,这里不再赘述。

运行ShieldJMHTest类的main()方法,会在命令行输出如下信息。

Benchmark                                (length)    Mode     Cnt     Score      Error   Units
ShieldJMHTest.jsonTest                        100   thrpt       5    70.562 ±    8.313  ops/ms
ShieldJMHTest.jsonTest                      10000   thrpt       5     0.721 ±    0.051  ops/ms
ShieldJMHTest.jsonTest                    1000000   thrpt       5     0.006 ±    0.005  ops/ms
ShieldJMHTest.noShieldUtilsTest               100   thrpt       5   253.883 ±   29.784  ops/ms
ShieldJMHTest.noShieldUtilsTest             10000   thrpt       5     2.545 ±    0.239  ops/ms
ShieldJMHTest.noShieldUtilsTest           1000000   thrpt       5     0.025 ±    0.003  ops/ms
ShieldJMHTest.shieldUtilsTest                 100   thrpt       5    13.718 ±    3.831  ops/ms
ShieldJMHTest.shieldUtilsTest               10000   thrpt       5     0.142 ±    0.016  ops/ms
ShieldJMHTest.shieldUtilsTest             1000000   thrpt       5     0.001 ±    0.001  ops/ms
ShieldJMHTest.toStringTest                    100   thrpt       5    83.366 ±   14.190  ops/ms
ShieldJMHTest.toStringTest                  10000   thrpt       5     0.847 ±    0.037  ops/ms
ShieldJMHTest.toStringTest                1000000   thrpt       5     0.008 ±    0.002  ops/ms
ShieldJMHTest.jsonTest                        100    avgt       5     0.165 ±    0.073   ms/op
ShieldJMHTest.jsonTest                      10000    avgt       5    14.674 ±    1.887   ms/op
ShieldJMHTest.jsonTest                    1000000    avgt       5  1378.764 ±  212.024   ms/op
ShieldJMHTest.noShieldUtilsTest               100    avgt       5     0.035 ±    0.001   ms/op
ShieldJMHTest.noShieldUtilsTest             10000    avgt       5     3.485 ±    0.199   ms/op
ShieldJMHTest.noShieldUtilsTest           1000000    avgt       5   358.319 ±   40.745   ms/op
ShieldJMHTest.shieldUtilsTest                 100    avgt       5     0.644 ±    0.079   ms/op
ShieldJMHTest.shieldUtilsTest               10000    avgt       5    73.711 ±   33.617   ms/op
ShieldJMHTest.shieldUtilsTest             1000000    avgt       5  6388.675 ± 1418.723   ms/op
ShieldJMHTest.toStringTest                    100    avgt       5     0.084 ±    0.007   ms/op
ShieldJMHTest.toStringTest                  10000    avgt       5     8.605 ±    0.253   ms/op
ShieldJMHTest.toStringTest                1000000    avgt       5   968.886 ±  171.419   ms/op
ShieldJMHTest.jsonTest                        100  sample  272852     0.148 ±    0.002   ms/op
ShieldJMHTest.jsonTest:p0.00                  100  sample             0.065              ms/op
ShieldJMHTest.jsonTest:p0.50                  100  sample             0.131              ms/op
ShieldJMHTest.jsonTest:p0.90                  100  sample             0.143              ms/op
ShieldJMHTest.jsonTest:p0.95                  100  sample             0.154              ms/op
ShieldJMHTest.jsonTest:p0.99                  100  sample             0.341              ms/op
ShieldJMHTest.jsonTest:p0.999                 100  sample             3.290              ms/op
ShieldJMHTest.jsonTest:p0.9999                100  sample            18.280              ms/op
ShieldJMHTest.jsonTest:p1.00                  100  sample            37.093              ms/op
ShieldJMHTest.jsonTest                      10000  sample    2571    15.673 ±    0.169   ms/op
ShieldJMHTest.jsonTest:p0.00                10000  sample            11.174              ms/op
ShieldJMHTest.jsonTest:p0.50                10000  sample            15.106              ms/op
ShieldJMHTest.jsonTest:p0.90                10000  sample            16.902              ms/op
ShieldJMHTest.jsonTest:p0.95                10000  sample            19.641              ms/op
ShieldJMHTest.jsonTest:p0.99                10000  sample            28.323              ms/op
ShieldJMHTest.jsonTest:p0.999               10000  sample            43.765              ms/op
ShieldJMHTest.jsonTest:p0.9999              10000  sample            47.579              ms/op
ShieldJMHTest.jsonTest:p1.00                10000  sample            47.579              ms/op
ShieldJMHTest.jsonTest                    1000000  sample      40  1522.165 ±   18.493   ms/op
ShieldJMHTest.jsonTest:p0.00              1000000  sample          1488.978              ms/op
ShieldJMHTest.jsonTest:p0.50              1000000  sample          1513.095              ms/op
ShieldJMHTest.jsonTest:p0.90              1000000  sample          1559.442              ms/op
ShieldJMHTest.jsonTest:p0.95              1000000  sample          1608.411              ms/op
ShieldJMHTest.jsonTest:p0.99              1000000  sample          1663.042              ms/op
ShieldJMHTest.jsonTest:p0.999             1000000  sample          1663.042              ms/op
ShieldJMHTest.jsonTest:p0.9999            1000000  sample          1663.042              ms/op
ShieldJMHTest.jsonTest:p1.00              1000000  sample          1663.042              ms/op
ShieldJMHTest.noShieldUtilsTest               100  sample  685547     0.032 ±    0.001   ms/op
ShieldJMHTest.noShieldUtilsTest:p0.00         100  sample             0.008              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.50         100  sample             0.024              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.90         100  sample             0.034              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.95         100  sample             0.040              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.99         100  sample             0.107              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.999        100  sample             1.481              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.9999       100  sample            11.542              ms/op
ShieldJMHTest.noShieldUtilsTest:p1.00         100  sample            43.123              ms/op
ShieldJMHTest.noShieldUtilsTest             10000  sample   10724     3.767 ±    0.063   ms/op
ShieldJMHTest.noShieldUtilsTest:p0.00       10000  sample             2.339              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.50       10000  sample             3.375              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.90       10000  sample             4.260              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.95       10000  sample             4.833              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.99       10000  sample            13.689              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.999      10000  sample            30.509              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.9999     10000  sample            40.466              ms/op
ShieldJMHTest.noShieldUtilsTest:p1.00       10000  sample            40.632              ms/op
ShieldJMHTest.noShieldUtilsTest           1000000  sample      85   359.514 ±    4.006   ms/op
ShieldJMHTest.noShieldUtilsTest:p0.00     1000000  sample           343.409              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.50     1000000  sample           357.040              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.90     1000000  sample           376.439              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.95     1000000  sample           384.775              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.99     1000000  sample           394.789              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.999    1000000  sample           394.789              ms/op
ShieldJMHTest.noShieldUtilsTest:p0.9999   1000000  sample           394.789              ms/op
ShieldJMHTest.noShieldUtilsTest:p1.00     1000000  sample           394.789              ms/op
ShieldJMHTest.shieldUtilsTest                 100  sample   60929     0.662 ±    0.010   ms/op
ShieldJMHTest.shieldUtilsTest:p0.00           100  sample             0.376              ms/op
ShieldJMHTest.shieldUtilsTest:p0.50           100  sample             0.592              ms/op
ShieldJMHTest.shieldUtilsTest:p0.90           100  sample             0.686              ms/op
ShieldJMHTest.shieldUtilsTest:p0.95           100  sample             0.836              ms/op
ShieldJMHTest.shieldUtilsTest:p0.99           100  sample             1.806              ms/op
ShieldJMHTest.shieldUtilsTest:p0.999          100  sample            13.489              ms/op
ShieldJMHTest.shieldUtilsTest:p0.9999         100  sample            25.541              ms/op
ShieldJMHTest.shieldUtilsTest:p1.00           100  sample            28.508              ms/op
ShieldJMHTest.shieldUtilsTest               10000  sample     620    65.028 ±    0.841   ms/op
ShieldJMHTest.shieldUtilsTest:p0.00         10000  sample            57.934              ms/op
ShieldJMHTest.shieldUtilsTest:p0.50         10000  sample            62.947              ms/op
ShieldJMHTest.shieldUtilsTest:p0.90         10000  sample            73.138              ms/op
ShieldJMHTest.shieldUtilsTest:p0.95         10000  sample            79.017              ms/op
ShieldJMHTest.shieldUtilsTest:p0.99         10000  sample            89.833              ms/op
ShieldJMHTest.shieldUtilsTest:p0.999        10000  sample           101.581              ms/op
ShieldJMHTest.shieldUtilsTest:p0.9999       10000  sample           101.581              ms/op
ShieldJMHTest.shieldUtilsTest:p1.00         10000  sample           101.581              ms/op
ShieldJMHTest.shieldUtilsTest             1000000  sample      40  6319.768 ±   75.590   ms/op
ShieldJMHTest.shieldUtilsTest:p0.00       1000000  sample          6148.850              ms/op
ShieldJMHTest.shieldUtilsTest:p0.50       1000000  sample          6295.650              ms/op
ShieldJMHTest.shieldUtilsTest:p0.90       1000000  sample          6442.451              ms/op
ShieldJMHTest.shieldUtilsTest:p0.95       1000000  sample          6458.389              ms/op
ShieldJMHTest.shieldUtilsTest:p0.99       1000000  sample          6970.933              ms/op
ShieldJMHTest.shieldUtilsTest:p0.999      1000000  sample          6970.933              ms/op
ShieldJMHTest.shieldUtilsTest:p0.9999     1000000  sample          6970.933              ms/op
ShieldJMHTest.shieldUtilsTest:p1.00       1000000  sample          6970.933              ms/op
ShieldJMHTest.toStringTest                    100  sample  461464     0.088 ±    0.001   ms/op
ShieldJMHTest.toStringTest:p0.00              100  sample             0.040              ms/op
ShieldJMHTest.toStringTest:p0.50              100  sample             0.078              ms/op
ShieldJMHTest.toStringTest:p0.90              100  sample             0.091              ms/op
ShieldJMHTest.toStringTest:p0.95              100  sample             0.097              ms/op
ShieldJMHTest.toStringTest:p0.99              100  sample             0.206              ms/op
ShieldJMHTest.toStringTest:p0.999             100  sample             1.726              ms/op
ShieldJMHTest.toStringTest:p0.9999            100  sample             9.539              ms/op
ShieldJMHTest.toStringTest:p1.00              100  sample            28.639              ms/op
ShieldJMHTest.toStringTest                  10000  sample    4311     9.361 ±    0.170   ms/op
ShieldJMHTest.toStringTest:p0.00            10000  sample             5.251              ms/op
ShieldJMHTest.toStringTest:p0.50            10000  sample             8.405              ms/op
ShieldJMHTest.toStringTest:p0.90            10000  sample            11.040              ms/op
ShieldJMHTest.toStringTest:p0.95            10000  sample            14.205              ms/op
ShieldJMHTest.toStringTest:p0.99            10000  sample            26.162              ms/op
ShieldJMHTest.toStringTest:p0.999           10000  sample            41.579              ms/op
ShieldJMHTest.toStringTest:p0.9999          10000  sample            48.366              ms/op
ShieldJMHTest.toStringTest:p1.00            10000  sample            48.366              ms/op
ShieldJMHTest.toStringTest                1000000  sample      43  1046.430 ±   21.243   ms/op
ShieldJMHTest.toStringTest:p0.00          1000000  sample           982.516              ms/op
ShieldJMHTest.toStringTest:p0.50          1000000  sample          1043.333              ms/op
ShieldJMHTest.toStringTest:p0.90          1000000  sample          1082.969              ms/op
ShieldJMHTest.toStringTest:p0.95          1000000  sample          1104.360              ms/op
ShieldJMHTest.toStringTest:p0.99          1000000  sample          1220.542              ms/op
ShieldJMHTest.toStringTest:p0.999         1000000  sample          1220.542              ms/op
ShieldJMHTest.toStringTest:p0.9999        1000000  sample          1220.542              ms/op
ShieldJMHTest.toStringTest:p1.00          1000000  sample          1220.542              ms/op
ShieldJMHTest.jsonTest                        100      ss       5     1.671 ±    4.069   ms/op
ShieldJMHTest.jsonTest                      10000      ss       5    40.512 ±   74.791   ms/op
ShieldJMHTest.jsonTest                    1000000      ss       5  1492.125 ±  600.438   ms/op
ShieldJMHTest.noShieldUtilsTest               100      ss       5     0.393 ±    0.246   ms/op
ShieldJMHTest.noShieldUtilsTest             10000      ss       5    10.892 ±   21.320   ms/op
ShieldJMHTest.noShieldUtilsTest           1000000      ss       5   365.444 ±   28.381   ms/op
ShieldJMHTest.shieldUtilsTest                 100      ss       5     6.838 ±    4.258   ms/op
ShieldJMHTest.shieldUtilsTest               10000      ss       5    82.848 ±   71.047   ms/op
ShieldJMHTest.shieldUtilsTest             1000000      ss       5  6693.834 ± 1547.212   ms/op
ShieldJMHTest.toStringTest                    100      ss       5     1.395 ±    1.128   ms/op
ShieldJMHTest.toStringTest                  10000      ss       5    33.314 ±  148.177   ms/op
ShieldJMHTest.toStringTest                1000000      ss       5   951.696 ±  140.549   ms/op
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

同时,会在项目的根目录输出jmh-result.json文件,如下所示。


可以将输出的jmh-result.json文件上传到 https://deepoove.com/jmh-visual-chart (opens new window) 生成图表,如下所示。


可以看到,通过高性能脱敏组件对数据进行脱敏的性能是非常高的。

# 四、本节总结

本节,主要对高性能脱敏组件进行了JMH基准性能测试,从测试结果来看,通过高性能脱敏组件对数据进行脱敏的性能是非常高的。

最后,可以在评论区写下你学完本章节的收获,祝大家都能学有所成,我们一起搞定高性能脱敏组件。

# 五、如何学习

1.加入 冰河技术 知识星球(文末有知识星球优惠券,即将涨价),才能查看星球专栏文章,学习专栏视频课程,查看星球置顶消息,申请加入项目,才能看到项目代码和技术小册,如果未申请加入项目,点击项目链接,你会发现是404页面。

2.专栏的每一章会对应一个代码分支,学习视频和专栏文章时,大家对照代码分支学习即可。

3.学习过程中最好按照章节顺序来学习,每一章前后都是比较连贯的,并且每一章的代码实现也有先后顺序,这样按照从前往后的顺序学习,最终你会实现一个完整的线程池项目。

注意:学习的过程,不是复制粘贴代码的过程,赋值粘贴代码是没有任何意义的,最好的学习方式就是自己动手实现代码,然后思考、总结。

4.代码结构:master分支是最新的全量代码,专栏中每一个章节和视频都会对应一个代码分支,切换到章节对应的代码分支后,即可根据当前章节和视频学习对应的代码实现,不然,在master分支中看到的是全量的代码。

5.对应代码实现上的问题,可以在专栏对应的源码提issuse。

6.冰河会为《高性能脱敏组件》专栏录制完整的视频课程。

# 六、写在最后

在冰河的知识星球除了高性能脱敏组件项目和热更的RPC视频外,还有其他十几个项目,像DeepSeek大模型、手写线程池、手写高性能SQL引擎、手写高性能Polaris网关、手写高性能熔断组件、手写通用指标上报组件、手写高性能数据库路由组件、手写分布式IM即时通讯系统、手写Seckill分布式秒杀系统、手写高性能RPC、实战高并发设计模式、简易商城系统等等,这些项目的需求、方案、架构、落地等均来自互联网真实业务场景,让你真正学到互联网大厂的业务与技术落地方案,并将其有效转化为自己的知识储备。

值得一提的是:冰河自研的Polaris高性能网关比某些开源网关项目性能更高,并且冰河也正在为企业级高性能RPC框架录制视频,全程带你分析原理和手撸代码。 你还在等啥?不少小伙伴经过星球硬核技术和项目的历练,早已成功跳槽加薪,实现薪资翻倍,而你,还在原地踏步,抱怨大环境不好。抛弃焦虑和抱怨,我们一起塌下心来沉淀硬核技术和项目,让自己的薪资更上一层楼。


目前,领券加入星球就可以跟冰河一起学习《DeepSeek大模型》、《手写线程池》、《手写高性能SQL引擎》、《手写高性能Polaris网关》、《手写高性能RPC项目》、《分布式Seckill秒杀系统》、《分布式IM即时通讯系统》《手写高性能通用熔断组件项目》、《手写高性能通用监控指标上报组件》、《手写高性能数据库路由组件》、《手写简易商城脚手架项目》、《Spring6核心技术与源码解析》和《实战高并发设计模式》,从零开始介绍原理、设计架构、手撸代码。

花很少的钱就能学这么多硬核技术、中间件项目和大厂秒杀系统与分布式IM即时通讯系统,比其他培训机构不知便宜多少倍,硬核多少倍,如果是我,我会买他个十年!

加入要趁早,后续还会随着项目和加入的人数涨价,而且只会涨,不会降,先加入的小伙伴就是赚到。

另外,还有一个限时福利,邀请一个小伙伴加入,冰河就会给一笔 分享有奖 ,有些小伙伴都邀请了50+人,早就回本了!

# 七、其他方式加入星球

  • 链接 :打开链接 http://m6z.cn/6aeFbs 加入星球。
  • 回复 :在公众号 冰河技术 回复 星球 领取优惠券加入星球。

特别提醒: 苹果用户进圈或续费,请加微信 hacker_binghe 扫二维码,或者去公众号 冰河技术 回复 星球 扫二维码加入星球。

好了,今天就到这儿吧,我是冰河,我们下期见~~