JVM冲击
JVM(如HotSpot虚拟机),实际上采用的是基于栈的指令集架构,它并没有依赖于寄存器,而是更多的利用操作栈来完成,这样不仅设计和实现起来更简单,并且也能够更加方便地实现跨平台,不太依赖于硬件的支持。
JVM运行字节码时,所有的操作基本都是围绕两种数据结构,一种是堆栈(本质是栈结构),还有一种是队列,如果JVM执行某条指令时,该指令需要对数据进行操作,那么被操作的数据在指令执行前,必须要压到堆栈上,JVM会自动将栈顶数据作为操作数。如果堆栈上的数据需要暂时保存起来时,那么它就会被存储到局部变量队列上。
线程私有的:
程序计数器
虚拟机栈
本地方法栈
线程共享的:
堆
方法区
直接内存 (非运行时数据区的一部分)
Java 虚拟机规范对于运行时数据区域的规定是相当宽松的。以堆为例:堆可以是连续空间,也可以不连续。堆的大小可以固定,也可以在运行时按需扩展 。虚拟机实现者可以使用任何垃圾回收算法管理堆,甚至完全不进行垃圾收集也是可以的。
程序计数器程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下 ...
RocketMQ火箭冲击
如何保证消息的可靠投递?
生产者的可靠投递 集群的持久化 消费者的消费确认
难点在于生产者这边,如何去保证消息的发送和数据的入库实现一致性
比如A给B转账100块
12345public void transfer(Long uid,Long tUid,int amount) { userAccountMapper.addAmount(sUid,-amount); userAccountMapper.addAmount(tUid,ammout); mqProducer.send("topic",new AccountChangeMsg(sUid,tUid,amount));}
第一如果需要发送两条mq呢?
第二条mq是在事务里面的,如果事务还没有执行成功,消费者就收到了消息,这时候回查查不到转账记录的。
解决办法:
1.消息入库,事务在提交之后 才发送消息,每条消息都不会直接发送都是直接存到数据库当中,将消息ID存入ThreadLocal当中
消息和其他的都是入库的,已经能严格保证数据库的事务了
2.消息之后的投递怎么做到的,需要重写事务管理器 ...
redis缓存技术再整理
基本常见的数据类型字符串 hash list set zset
字符串:
哈希: Hash的命令前面多了个H,类似java里面的Map<String,Map<String,String>> 这种格式,比较适合存储类这种数据。
List: 类似LinkedList一样,
向头部添加数据
1lpush linkedlist 1 2 3
– 向尾部添加数据
1rpush linkedlist 1 2 3
向指定元素前面后面插入元素
1linsert linkedlist before/after 1 4
blpop有点类似阻塞的这种形式
1blpop linkedlist 10
set:跟着HashSet一样可以过滤
1sadd <key> <value>
ZSet 类似java里面的TreeSet
1zadd <key> [<value> <score>]...
持久化RDB快照
123save-- 注意上面这个命令是直接保存,会占用一定的时间,也可以单独开一个子进程后台执行保存b ...
java多线程
线程的创建和启动通过创建Thread对象来创建一个新的线程,Thread构造方法中需要传入一个Runnable接口的实现(其实就是编写要在另一个线程执行的内容逻辑)同时Runnable只有一个未实现方法,因此可以直接使用lambda表达式:
1234567891011121314public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 0; i < 50; i++) { System.out.println("我是一号线程:"+i); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 50; i++) { System.out.println("我是二号线程:"+i); ...