0%

Jvm 如何确定方法的参数的个数

找到 Method 的 DescriptionIndex 的属性,找到对应的描述,例如:

1
2
3
4
5
6
7
8
9
10
11
public class AddMain {
public static void main(String[] args) {

int c = add(100,200);
System.out.println(c);
}

private static int add(int a, int b) {
return a + b;
}
}

这个例子中的 java 代码,add 方法对应的代码是 (II)I,最后一个 I 代表返回值,这个代表两个整型的参数.

1
2
3
private static int add(int a, int b,String c,boolean d) {
return a + b;
}

​ 同样,(IILjava/lang/String;Z)I 代表有4个参数,字符串的表示是:Ljava/lang/String;,解析比较特殊。

阅读全文 »

java的运行过程

在运行一段 java 代码的时候需要经过编译,验证,加载运行,具体如下图:

运行过程

对于 Java 源码变成字节码的编译过程,我们暂且跳过不讨论。

想弄清楚 java 代码的运行原理,其实本质就是 java 字节码如何被 jvm 执行。

下面我们就从两个方面去认识字节码:

  1. 字节码是什么?
  2. 字节码如何被执行的?

我们先写一个简单的 java 程序:

1
2
3
4
5
6
7
8
9
10

public class AddMain {
public static void main(String[] args) {
int a=1;
int b=2;
int c=a+b;
System.out.println(c);
}
}

阅读全文 »

在学习的JVM的时候,最重要的是认识JVM的指令,JVM指令很多,为了方便记忆,可以根据前缀和功能进行分类:

例如:nop指令代表是一个空指令,JVM收到指令后,什么都不用做,等待下一个指令。


const把数据推至栈顶

const的范围从0x01—0x0f,负责把数据推送到栈顶。例如:iconst_0负责吧整型的0推送到栈顶。 fconst_0负责把float的0推送到栈顶。const可以分为以下几种类型:

iconst_:把int推送栈顶
fconst_:推送float类型栈顶
lconst_:推送long到栈顶
dconst_:提送double至栈顶

上述的为简写的前缀,后续可以跟参数,例如:iconst_0,iconst_1分别代表推送0和1至栈顶。


push常量到栈顶

阅读全文 »

访问者模式

访问者模式是一种对象和对象的访问者分开的一种设计模式,在一个对象稳定的情况下,使用访问者模式可以更好的扩展对数据的访问。 相当于是我们在对象里面安插了一个“眼”,这个眼能够被外面实现,然后能拿到当前对象的各个属性。

举个例子

组装一台电脑,对于组装的对于组装者来说,只关心一个电脑零件构成(CPU,内存,鼠标键盘)。而对于电脑的消费者,关心的是电脑各个零件的价格以及总价。 而对于有些人来说对于,可能只关心电脑各个零件的重要性以及核心程度。综上所述我们操作的对象是一个电脑,对象是不变的,电脑的访问者来说是不同的,他们从不同的维度来分析这个电脑的属性。下面我们就用类图来表示访问者模式的大概结构:

访问者模式

对于访问者模式来说有以下几个实现步骤:

  1. 定义一个对象(可以是一个基类,也可是其他)

    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
    public class ComputerPartBase   {
    private final String partName;
    private final int coreLevel;
    private final double price;

    public ComputerPartBase(String partName, int coreLevel, double price) {
    this.partName = partName;
    this.coreLevel = coreLevel;
    this.price = price;
    }

    public String getPartName() {
    return partName;
    }

    public int getCoreLevel() {
    return coreLevel;
    }

    public double getPrice() {
    return price;
    }

    }

  2. 定义一个接口,实现”插眼”的约束

    1
    2
    3
     public interface ComputerVisitor {
    public void accept(ComputerPartVisitor computerPartVisitor);
    }
  3. 对象继承”眼“,实现方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
      public class ComputerPartBase implements ComputerVisitor {

    //.....

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {

    }
    }
  4. 各个零件的实现

    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
     public class CPU  extends ComputerPartBase {
    public CPU() {
    super("CPU", 10,2000.00d);
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
    computerPartVisitor.visit(this);
    }
    }

    public class Keyboard extends ComputerPartBase implements ComputerVisitor {
    public Keyboard() {
    super("keyboard", 1, 10);
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
    computerPartVisitor.visit(this);
    }
    }

    public class Memery extends ComputerPartBase implements ComputerVisitor {
    public Memery() {
    super("memery", 8, 200d);
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
    computerPartVisitor.visit(this);
    }
    }

    public class Monitor extends ComputerPartBase implements ComputerVisitor {
    public Monitor() {
    super("monitor", 2, 800);
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
    computerPartVisitor.visit(this);
    }
    }

    public class Mouse extends ComputerPartBase implements ComputerVisitor {
    public Mouse() {
    super("mouse", 2, 100);
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
    computerPartVisitor.visit(this);
    }
    }

  5. 真正的”眼“的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9

    public interface ComputerPartVisitor {
    public void visit(CPU cpu);
    public void visit(Memery memery);
    public void visit(Mouse mouse);
    public void visit(Keyboard keyboard);
    public void visit(Monitor monitor);
    }

  6. 访问者通过实现来获取数据

    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
    //电脑的组成
    public class ComputerPartStrutchNameVisitor implements ComputerPartVisitor {

    private List<String> partSet=new ArrayList<>();
    @Override
    public void visit(CPU cpu) {
    partSet.add(cpu.getPartName());
    }

    @Override
    public void visit(Memery memery) {
    partSet.add(memery.getPartName());

    }

    @Override
    public void visit(Mouse mouse) {
    partSet.add(mouse.getPartName());

    }

    @Override
    public void visit(Keyboard keyboard) {
    partSet.add(keyboard.getPartName());

    }

    @Override
    public void visit(Monitor monitor) {
    partSet.add(monitor.getPartName());

    }

    public String getNeedPart(){
    return partSet.stream().collect(Collectors.joining(","));
    }
    }

    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

    //电脑的组装价格
    public class ComputerPartPriceVisitor implements ComputerPartVisitor {

    private double price = 0d;

    @Override
    public void visit(CPU cpu) {
    price += cpu.getPrice();
    }

    @Override
    public void visit(Memery memery) {
    price += memery.getPrice();

    }

    @Override
    public void visit(Mouse mouse) {
    price += mouse.getPrice();
    }

    @Override
    public void visit(Keyboard keyboard) {
    price += keyboard.getPrice();

    }

    @Override
    public void visit(Monitor monitor) {
    price += monitor.getPrice();
    }
    public double getPrice(){
    return price;
    }
    }

    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
    //获得电脑的核心等级
    public class ComputerPartCoreLevelVisitor implements ComputerPartVisitor {

    private List<String> levelList = new ArrayList<>();

    @Override
    public void visit(CPU cpu) {

    levelList.add("CPU:"+cpu.getCoreLevel());
    }

    @Override
    public void visit(Memery memery) {
    levelList.add("Memery:"+memery.getCoreLevel());
    }

    @Override
    public void visit(Mouse mouse) {
    levelList.add("Mouse:"+mouse.getCoreLevel());
    }

    @Override
    public void visit(Keyboard keyboard) {
    levelList.add("Keyboard:"+keyboard.getCoreLevel());
    }

    @Override
    public void visit(Monitor monitor) {
    levelList.add("Monitor:"+monitor.getCoreLevel());
    }
    public String getCoreLevel(){
    return levelList.stream().collect(Collectors.joining(","));
    }
    }

  7. 调用的实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class AppMain {
    public static void main(String[] args) {
    Computer computer = new Computer();
    ComputerPartStrutchNameVisitor computerPartVisitor = new ComputerPartStrutchNameVisitor();
    computer.accept(computerPartVisitor);
    System.out.println("组装一个电脑需要零件:" + computerPartVisitor.getNeedPart());

    ComputerPartPriceVisitor computerPartPriceVisitor = new ComputerPartPriceVisitor();
    computer.accept(computerPartPriceVisitor);
    System.out.println("组装一个电脑需要Money:" + computerPartPriceVisitor.getPrice());

    ComputerPartCoreLevelVisitor computerPartCoreLevelVisitor = new ComputerPartCoreLevelVisitor();
    computer.accept(computerPartCoreLevelVisitor);
    System.out.println("电脑硬件的核心优先级为:" + computerPartCoreLevelVisitor.getCoreLevel());
    }
    }

输出的结果为:

1
2
3
组装一个电脑需要零件:CPU,memery,monitor,keyboard,mouse
组装一个电脑需要Money:3110.0
电脑硬件的核心优先级为:CPU:10,Memery:8,Monitor:2,Keyboard:1,Mouse:2
阅读全文 »

一直想写一个秒杀系统的设计,网上有烂大街的教程,虽然有的写得很不错,但是还是自己设计的来的清楚,基本思路就是拦截+负载+缓存+异步,流程如下(文字改天补上):

秒杀系统的设计

阅读全文 »

在23种设计模式中,装饰者模式在游戏开发的过程中,使用的很是频繁。因为这个设计模式,把所有的业务的逻辑封装的对应的实体类中,从而为主流程减负了。首先看下一个应用场景

装饰者模式的应用

我们都知道有一款经典游戏90坦克,这个游戏中,玩家坦克来操作坦克打击AI敌人,在没打死一个红色坦克就会掉下来一个装备,这个装备可以提升移动速度,增加攻击力。

我们首先定义玩家坦克是player对象,再定义几个特别的装备,增加速度,增加生命,增加攻击力。对于这个场景,可以定制一下几个方法:

1
2
3
4
5

void addSpeed(Player player);
void addLife(Player player);
void addAttack(Player player);

这个方法定下来,就可以设计我们的程序,怎么设计呢? 我们可以设计一个最简单的设计,写一个静态的帮助类,代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class EquipmentHelper{
public void addSpeed(Player player){

}
public void addLife(Player player){

}
public void addAttack(Player player){

}

}

这个写完之后,我们们觉是可以实现我们的功能的?但是我们在条用的时候,是不是判断的逻辑比较多?如果类型比较多的时候,我们的系统就很难再维护了。

1
2
3
4
5
6
7
if(equipment is Speed){
equipmentHelper.addSpeed(player);
}
if(equipment is Life){
equipmentHelper.addLife(player);
}
....
阅读全文 »

启动zookeeper

1
2
$ bin/zkServer.sh start conf/zoo.cfg &
$ bin/zkCli.sh

启动Kafka

我们启动两个实例:

1
2
3
$ bin/kafka-server-start.sh -daemon config/server.properties
$ bin/kafka-server-start.sh -daemon config/server-1.properties

启动后,使用jps进程查看对应的kafka进程:
Kafka常用的命令

创建主题

现在我们来创建一个名字为testTopictestTopic1 的Topic,这个topic有两个partition,并且备份因子也设置为2:

1
2
$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 2 --partitions 2 --topic testTopic
$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 2 --partitions 2 --topic testTopic1

查看Kafka的实例

1
2
3
4
$ bin/zkCli.sh 
$ ls / #查看zk的根目录kafka相关节点
$ ls /brokers/ids #查看kafka节点

阅读全文 »

未选择的路
(罗伯特·弗罗斯特)

黄色的树林里分出两条路
可惜我不能同时去涉足
我在那路口久久伫立
我向着一条路极目望去

直到它消失在丛林深处
但我却选择了另外一条路
它荒草萋萋,十分幽寂
显得更诱人,更美丽
虽然在这条小路上
很少留下旅人的足迹
那天清晨落叶满地
两条路都未经脚印污染
呵,留下一条路等改日再见
但我知道路径延绵无尽头
恐怕我难以再回返
也许多少年后在某个地方,
我将轻声叹息将往事回顾:
一片树林里分出两条路——
而我选择了人迹更少的一条,
从此决定了我一生的道路。

阅读全文 »

Kafka是基于partition的模型,在消费的时候,消费者会和kafka建立一个绑定的关系。假设有一个topic有3个partition:P1,P2,P3,同时有一个消费group对应有3个消费者:C1,C2,C3,则消费会建立一个P1-C1,P2-C2,P3-C3的关系。

Kafka的文件机制

如果消费者数量多于partirion的话,就会有消费者空闲。

Kafka的文件机制

而如果partition个数比consumer个数多,则有可能导致有的消费者存在比其他消费者多的情况:

Kafka的文件机制

所以,kafka的最合理的分配机制是partition与consumer的成倍数关系,而且一个partition只能被一个消费者消费。

交代了Kafka的基本模型,下面再说几个疑问:

  1. 一个Consumer是什么意思,一个线程还是进程?
  2. 消费组是什么含义?
  3. 为什么一个partition不能被多个Consumer消费?
阅读全文 »