avatar

目录
java模块学习

[TOC]

吾生也有涯,而知也无涯

缺乏一个正确的、高效的学习方向

希望能够站在一个相对正确的角度去看待要学习的内容

​ (1)、业务维度

​ ssm —> 分布式 —> 微服务 [需要学习那些知识]

​ (2)、非业务维度

​ 怎么样除了业务维度,提升自己的技术能力、技术修养、技术内容,然后对业务有一个相辅相成的作用。

1、ConsurrentHashMap 源码解读

ConcurrentHashMap

  • 数据结构
    • 数组 + 链表 + 红黑树
    • 数组是基础结构;key相同的时候用到链表;链表长度过长则使用红黑树;
  • HashTable 是在整个数组上加Sync,锁的粒度较大;
  • CHM使用comparaAndSwap 粒度只到数组对象级别,只在数组对象上加锁,比较友好;
  • CHM 在扩容时使用单线程 保证线程安全;同时其他线程也不会闲着,会帮忙协助进行数据重新赋值。

2、Spring boot 核心原理

1、Spring boot相对Spring来说解决了那些痛点?
2、Spring boot的自动装配是怎么实现的?

  • Spring boot是Spring的升级版,整合集成了Spring framework、IOC、AOP等优秀思想。主要解决的是SpringMVC在常见web项目是复杂繁琐重复的JAR依赖、版本排查、web.xml、springMVC.xml等配置文件工作,使用“自动转配”的方式,一键化创建springWeb项目(仅需配置application.properties或application.yml文件)。详情可参考
  • 自动装配使用到的注解:
    • @SpringBootApplication
    • @Configuration
    • @EnableAutoConfiguration
    • @Bean
    • @Import / @ImportSource
    • @ComponentScan
  • 怎么将第三方的类放到容器中?规范的作用来了。统一加载类的路径或规范(spring.factories),通过一个个”start”,来加载 xxxAutoConfiguration 来批量装配

3、JVM 基础学习

屏蔽操作系统

Java内存分解和各作用
  • 堆 : 存放 对象和数组;

  • 本地方法区:常量池和类、方法的描述;

  • java虚拟机栈:java方法的栈帧;

  • 本地方法栈:本地方法的栈帧(C、C++等)

  • PC 计数器:

    垃圾回收
  • 判断一个对象是否为垃圾

    • 引用计数法
    • 可达性分析
  • 有哪些垃圾回收算法可进行回收

    • 标记-清楚
    • 复制
    • 标记-整理
    • 分代回收
  • 通过垃圾收集器进行对垃圾回收算法进行实现

    • 新生代收集器:Serial、ParNew、Parallel Scavenge
    • 老年代收集器:CMS、Serial Old、Parallel Old
    • 整堆收集器: G1
  • 评价垃圾回收算法的优劣

    • 吞吐量

    • 停顿时间

    • 垃圾收集次数

      追求高吞吐、低停顿、少收集次数

      JVM实战
  • JVM参数

    • 有哪些常用的参数
      • 堆、方法区、Java虚拟机栈、启动时间等
  • JVM命令

    • jps、jinfo、jmap、jstack
  • JDK一些工具

    • 日志: gc-viewer、gceasy

    • 堆: MAT、PerfMa、heaphero.io

4、AQS分析学习

AQS = AbstrarctQueuedSynchronizer

1、数据安全产生的原因?怎么解决

  • 可见性
    • JMM[java内存模型]、valatile、synchornized、lock
  • 有序性
    • 指令重排序 synchornized、lock
  • 原子性
    • 要么都执行,要么都不执行
    • AtomicInteger、AtomicDouble等原子类
    • synchornized、lock

2、锁的前后流程是怎么设计的?

  • lock
    • 竞争锁
      • ``` java
        // 简单示例
        int state = 0
        if (state == 0) {
            // 表示获取锁
        } else {
            // 表示竞争锁失败,等待
        }
        Code
        1
        2
        3
        4
        5
        6
        7
        8
        ``` java
        final void lock() {
        if (compareAndSetState(0, 1))
        // 设置当前线程为“锁的拥有者”
        setExclusiveOwnerThread(Thread.currentThread());
        else
        acquire(1);
        }
    • 没有竞争到锁的线程存储
      • 队列、链表、数组等;
        java
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        // 使用链表
        private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
        pred.next = node;
        return node;
        }
        }
        enq(node);
        return node;
        }
    • 没有竞争到锁的线程阻塞
      • wait
      • condition
      • lockSupport.park()
        java
        1
        2
        3
        4
        private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
        }
  • unlock
    • 释放锁
      • state –
    • 唤醒
      • lockSupport.unpark()

3、可重入锁是干什么用的?怎么实现的?

  • 某一个程序在进入A锁后,如果还需要进行B函数中,此时如果B函数也需要加锁,如果不是可重入锁,则在这里会造成死锁现象;
  • Lock的实现是设置了一个”state”标识加锁与否,另有一个标识当前“锁的拥有者”是否为当前锁,如果是同一个则可以进入另一个锁,就不会造成死锁了。

5、RabbitMQ从工作机制到延时队列的实战

1、RabbitMQ工作机制
2、延时策略回调

  • CAP
    • 消息中间件- 保证服务可用,也就是AP;
  • 消息中间件运用场景
    • 解耦;
    • 异步;
    • 削峰/填谷
    • 顺序保证;
    • 可靠传递;
    • 最终一致性;
    • 事件编程;
  • 消息中间件带来的风险
    • 系统可用性风险;
    • 系统复杂性提高;
    • 数据的一致性保证;
      买火车票的时候,下单后30分钟内支付,否则订单取消

      1、延迟队列
      2、定时任务 + 数据表 (不好)

怎么实现延迟队列?

  • TTL + 死信

RabbitMQ中的死信和处理方案

  • 死信:
    • RabbitMQ consumer主动拒绝消费;
    • 消息的TTL(time to live)过期;
    • 消息在加入队列时超过队列中消息的长度;
  • 解决方案:
    • 当消息成为死信后,若该队列配置了死信交换机,则将该消息按规则转发给该交换机(主题交换机);若没有配置死信交换机,则消息丢失,不再处理(消息消失)

6、跨域单点登录原理分析及实战

一次登录,导出乱跑

CAS流程图,也是单点登录标准流程图

单点登录原理图

Token的生成有讲究的

  • 确保安全性
  • 能验证其正确性

JWT:Java web Token
基于不同的加密算法,以及author、timestamp、xxx参数等 ——> 作为参数 ——> 生成一个结果
Java:引入jwt包 —— 使用对应的工具类

sessionId的有效性问题

session 假设20分钟

sso.com sessionId/token
order.com sessionId/token
user.com seeeionId/token

彼此的有效性就要考虑了(其中一个过期了,其他的怎么办?)

  • 子模块先到期了,sso没有过期,怎么办?

此时不用办,sso没有过期,此时有全局的sesson和token,子模块来访问时,再重新颁发token即可,并创建局部session对象;

  • sso过期了,子模块没有过期,怎么办?

续签的操作。重新创建一个全部的session对象,或者token重新生成一次,然后颁发给子模块;

  • 注销的问题,意味着sessionId过期了,所有子模块全部过期,并且需要重新登录

    一次注销,全部注销

在sso维护一个列表,记录所有子模块的信息,然后注销所有的子模块;

在微服务场景下【1000个服务】——》sso.server ——》是不是没有服务都要写一份处理和sso交互的代码呢?
答案是不需要。我们可以设计一个解决方案:

  • sso.client ——》需要进行单点登录的服务就可以直接引入这个包,然后进行相应配置即可。

  • sso-server.jar ——》部署

  • sso-client.jar ——》需要用到的引入jar包,并进行一些简单的配置

Central Authentiacation Service: CAS 单点登录方案
Auth2协议 是怎么实现单点登录的?
Spring Security是怎么实现的?

总结

单点登录要做的事情:

  • 单点登录(SSO系统)是保证各业务系统的用户资源的安全;
  • 各个业务系统获得信息是,这个用户能不能访问我的资源;
  • 单点登录,资源都在业务系统模块这边,不在SSO系统中;
    • 用户在给SSO服务器提供用户名、密码等信息后,作为业务系统并不知道这件事;
    • SSO随便给业务系统返回一个ST(Service Ticket),那么业务系统是不知道这个ST是用户伪造的,还是真实有效的。
    • 所以,业务系统需要拿着这个ST去SSO系统中验证一下,用户给我的ST是否有效,有效的话我才能让这个用户访问我的资源;

7、百万级数据ID生成方案

1、分布式ID

不管在什么地方(何地),在什么时候(何时),都要保证这个ID是全局唯一的,

2、分布式ID生成方案

(1)、数据库自增ID

  • 单独一个数据库表记录和产生ID

  • 自增步长 和 起始值

  • 订单ID, 1、2、3、4……

  • 泄露我们公司敏感的信息 — 瑞幸

  • 不该返回的信息不要返回

  • 根据ID 猜测出订单量

  • 缺点

    • 不利于扩展

    • 会暴露敏感信息

(2)、UUID

  • 日期时间、 时钟序列、 全局唯一机器ID、算法生成 — hash冲突 (基本上唯一,不保证唯一)

  • 有5个版本

    • 1、日期+mac地址;会暴露mac地址,私密性不好
    • 2、DCE;
    • 3、基于字符的MD5算法;
    • 4、随机的UUID;
    • 5、基于字符的SHA1算法;
  • 缺点:

    • mysql是个B+树,而UUID是随机的,不适合做数据库主键;
    • 可读性低,字符串占内存等等

(3)、redis

  • incr() 函数
  • 单线程 — 命令执行 — 每个命令都是原子性 (redis 6.0后有了”多线程”,这个是针对网络请求、数据处理,命令执行的话还是单线程)

(4)、snowflake

1位符号bit + 41位时间戳bit + 10位机器bit + 12位序列号bit = 64bit — > 10进制数字

可套用公式 — 自己实现雪花算法

8、分布式Dubbo框架的核心探秘

1、Dubbo的本质是RPC服务框架;

2、RPC的理解及各阶段的实现方式;

3、用一个小时实现自己RPC通讯机制;

4、学习、理解RPC的演化过程;

RPC:remote procedure call

序列化和反序列化 (因为网络跨应用调用,底层是通过二进制字节码传输)

动态代理 — 》 保护 和 增强 方法;

spring[IoC, AOP]
Mybatis[mapper文件接口, 动态代理]
Dubbo[SPI, RPC]
Tomcat
spring cloud一些组件实现 [Feign, Ribbon]

文章作者: 海东青
文章链接: https://haohaogit.github.io/2020/08/13/java%E6%A8%A1%E5%9D%97%E5%AD%A6%E4%B9%A0/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hexo
打赏
  • 微信
    微信
  • 支付宝
    支付宝