Java 的五种代理实现方式
前言
本文主要介绍 Java 的五种代理实现方式,包括 Cglib、ASM、Javassist、Byte Buddy、JDK 代理,点击 下载完整的案例代码。
准备工作
先定义出一个接口和相应的实现类,方便后续使用代理类在方法中添加日志信息。
- 接口
1 | public interface IUserApi { |
先来一个天真的估算算法:假设要求一个系统的 TPS(Transaction Per Second 或者 Task Per Second)至少为 20,然后假设每个 Transaction 由一个线程完成,继续假设平均每个线程处理一个 Transaction 的时间为 4s。那么问题可以转化为:如何设计线程池大小,使得可以在 1s 内处理完 20 个 Transaction?这里计算过程可以很简单,每个线程的处理能力为 0.25TPS,那么要达到 20TPS,显然需要 20/0.25=80 个线程。
很显然这个估算算法很天真,因为它没有考虑到 CPU 数目。一般服务器的 CPU 核数为 16 或者 32,如果有 80 个线程,那么肯定会带来太多不必要的线程上下文切换开销。
第二种估算算法比较简单,但不知是否可行(N 为 CPU 总核数):
如果一台服务器上只部署这一个应用并且只有一个线程池,那么这种估算或许合理,具体还需自行测试验证。
本文主要介绍如何检测 Java 代码规范与格式化 Java 代码,包括 IDEA 插件与 Maven 插件的使用。
IDEA 可以使用 CheckStyle-IDEA 插件来检测 Java 代码的规范,它可以保证每位提交者的代码规范都保持一致。值得一提的是,CheckStyle-IDEA
插件只能检测代码的规范,并不能格式化代码。
在项目中创建 checkstyle.xml
规则文件,例如路径为 config/checkstyle/checkstyle.xml
。
提示
8.30
本文将介绍 VuePress 如何渲染 Mermaid 绘图,适用于 VuePress 1.x 与 VuePress 2.x。
VuePress 1.x 可以直接安装第三方插件 vuepress-plugin-mermaidjs 来渲染 Mermaid 绘图,插件的详细文档可看 这里。
安装插件时必须指定具体的版本号,否则默认会安装最新版本的插件,最新版本不兼容 VuePres 1.x。
1 | $ npm install vuepress-plugin-mermaidjs@1.9.1 -D |
编辑 VuePress 1.x 的 .vuepress/config.js
配置文件,新增 mermaidjs
插件,如下所示:
1 | module.exports = { |
本文使用了 DockerHub 平台上的 Oracle 11g 镜像,基于 Ubuntu 18.04 LTS 系统,数据库版本是 Oracle Express Edition 11g Release 2 (11.2.0.2.0)。
在 Oracle 数据库的发展中,数据库一直处于不断升级状态,一共有以下几个版本:
Oracle 8i
:Oracle 8i 表示 Oracle 正式向 Internet 上发展,其中 i 表示就是 internet。Oracle 9i
:Oracle 8i 是一个过渡版本,Oracle 9i 是一个更加完善的数据库版本。Oracle 10g
:g 表示 grid,代表网格的意思,即这种数据库采用网格计算的方式进行操作。Oracle 11g
:是 Oracle 10g 的稳定版本,Oracle 11g 是目前使用最广泛的版本。Oracle 12c
:是 Oracle 2013 年推出的数据库版本,c 代表 Cloud,代表云计算的意思,同时 Oracle 12c 支持大数据的处理能力。Oracle 18c、Oracle 19c
是对 12c 版本的完善和发展。函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而 C++ 通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL 就利用了这一点提供了相当多的算法。它是在一个有效的框架中完成这些算法的 —— 可以将所有的类型划分为少数的几类,然后就可以在模板的参数中使用一种类型替换掉同一种类中的其他类型。
尽管函数指针被广泛用于实现函数回调,但 C++ 还提供了一个重要的实现回调函数的方法,那就是函数对象。重载函数调用操作符 ()
的类,其对象常称为函数对象(Function Object),即它们是行为类似函数的对象。一个类对象,表现出一个函数的特征,就是通过 对象名 + (参数列表)
的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待,这是通过重载类的 ()
操作符来实现的。在 C++ 标准库中,函数对象被广泛地使用以获得弹性,并且标准库中的很多算法都可以使用函数对象或者函数来作为自定义的回调行为。值得一提的是,函数对象的别名是 仿函数
,或者是 伪函数
。
本文适用于在 Centos/Debian/Ubuntu 等 Linux 发行版系统上,使用多台物理机器(至少三台)搭建 Kafka 集群。
本文的 Kafka 集群搭建依赖于 Zookeeper,因此生产环境需要将 Zookeeper 集群提前搭建起来。值得一提的是,从 Kafka 2.8.0
版本开始,Kafka 自身实现了 Raft
分布式一致性机制,这意味着 Kafka 集群是可以脱离 ZooKeeper 独立运行的。
节点 | IP 地址 | 端口 | 版本号 |
---|---|---|---|
Zookeeper 节点 1 | 192.168.1.1 | 2181 | 3.4.10 |
Zookeeper 节点 2 | 192.168.1.2 | 2181 | 3.4.10 |
Zookeeper 节点 3 | 192.168.1.3 | 2181 | 3.4.10 |