java复习


1.java对象内存布局及对象大小

https://blog.csdn.net/loveyour_1314/article/details/123338536

1.java对象结构=对象头+数据区+对齐空间
2.java对象头大小=32位/64位=mark workd + class pointer + arrayLength(仅仅只有数组;集合不算)
3.mark workd:存储了对象的hashcode、分带年龄、锁的信息等3大部分;
4.class pointer(元数据):元数据指针,指向某一个类
5.class pointer默认大小是64bit=8byte,jdk1.8默认压缩为4byte,如果不压缩,通过重启动参数配置(不开启指针压缩 (-XX:-UseCompressedOops))

6.new Object对象,会占用16字节内存=8字节mark word + 4字节classpointer + 4字节对齐填充
7.一个空数组int[] ,会占用16字节内存= 8 字节markword + 4 字节classpointer+4字节数组长度

2.java锁的优缺点

锁的种类优点缺点场景
偏向锁获得锁执行代码与无锁时执行的效率只存在纳秒级别的误差多线程竞争时,锁的撤销会额外消耗cpu适合一个线程的场景
轻量级锁锁竞争时不会阻塞,提高了程序性能如果始终竞争不到锁,会一直cas自选耗CPU追求响应时间;同步代码快执行很快
重量级锁竞争时无cas操作,无cpu消耗线程阻塞,响应时间慢追求吞吐量,同步代码块执行速度过长

3.volatile:可见性和有序性

可见性原理:被volateile修饰的变量 jvm会将class解析成cpu指令,并在指令前加lock;
1.变量值被修改后,会被写会系统内存
2.一个处理器缓存写回系统内存时,会导致其他处理器缓存失效。

有序性原理:
原因:jvm在不改变数据依赖性的情况下,允许编译器和处理器对指令进行重排序,会导致在cpu指令上运行的顺序是不一样的;
通过volatile的内存屏障保证 指令不会被重新排序

4.计数器实现方式?

sync,cas,cas+分段思想

syncronized:
AtomicLong:
LongAdder:
AtomicCucculator:

AtomicLong:底层就是采用unsafe进行cas自选操作对值进行变更

CAS引发ABA问题
cas引发的 ABA问题:加版本号解决或 AtomicStampedReference<>,AtomicMarkableReference ;
AtomicStampedReference原理:
底层定义了私有的静态类pair并volatile修饰保证类的可见性,该类有两个属性,一个是reference即是value值,一个是int类型的stamp对象,用于记录版本号;
AtomicStampedReference使用cas方法时实际是对pair对象进行操作;如果版本不一致pair对象是不一致的,所以++++++

AtomicMarkableReference原理: 与AtomicStampedRefrence 原理类似,只是该类的pair对象是用bool类型的mark变量来标记版本是否变更

LongAdder:只能指定初始值为0
内部结构:底层采用了long类型的base对象和一个cell数组实现
操作原理:
当没有线程竞争的情况下:unsafe对象直接对base进行cas操作
当多线程竞争的情况下:longAdder会初始化一个cell数组,对每个线程的hash值与数组长度做&(与运算)并将value存放在对于的cell中,
之后将所有cell单元格的value与base值求和得到最终值;如果cas失败,则重新获取新的下标值去更新,在多线程情况下大大减少了cas失败的概率,极大减少了cpu的损耗

LongAccumulator:原子累加器原理
1.双目运算器,用于保存累加规则
2.identity指定初始值相当于longadder的base值
原理于longadder类似;LongAdder可以理解为LongAccumulator的一个特例

unsafe类作用
1.内存管理:包括分配内存,释放内存
2.操作类、对象、变量:通过获取当前对象和偏移量直接修改数据
3.挂起与恢复:将线程阻塞或恢复
4.cas:调用cpu的cas指令进行比较和交换
5.内存屏障:定义内存屏障,避免指令重排序

1.feign用的什么http框架;
httpUrlConnection(默认),httpclient,okHttp(最终使用)等
如果想更换http请求框架直接pom文件中指定即可


okHttp核心初衷:专注简单与高效;优点如下
1.支持http/2;http2通过多路复用在一个tcp连接上支持并发
2.如果http/2不可用,连接池复用技术也可以极大减少延迟
3.支持gzip,可以压缩下载体积
4.响应缓存可以直接避免重复请求
5.连接出现问题会自动恢复
6.如果服务配置了很多ip,其中一个失效时,会自动尝试下一个
7.处理代理问题和ssl握手失败的问题


2.hystix服务隔离策略
信号量隔离和线程池隔离?

4.redis如何实现分布式锁

5.rocket mq事务失败怎么处理
消费者消费失败 -> 进入重试队列(重试次数16次)-> 进入死信队列
死信队列的消息默认保存3天,需要人为处理
如何处理:在控制台查到死信队列的topic,在消息列表对消息进行重投,让消费者

rocket mq使用几阶段提交?
记录日志表通知开发人员处理

5.实现一个springboot的starter

实质是springboot的装配原理:核心注解@EnableAutoConfiguration

5.1 原理

@EnableAutoConfiguration主要导入了@AutoConfigurationImportSelector实现

@AutoConfigurationImportSelector的selectImports方法最终是通过SpringFactoriesLoader加载器的会去所有依赖包下找到META-INF/spring.factories文件通过全类名进行加载;
该文件里都会声明该依赖所提供的核心功能bean配置信息并进行加载,从而达到加载全部bean信息;

注意:多个暴露的服务用英文逗号隔开
在这里插入图片描述

5.2 实现自定义的starter

1.编写暴露服务的service(DemoService)
2.编写配置类的config(DemoConfig)
@Configarution注解到类上,@Bean注解创建DemoService
3.创建META-INF/spring.factories文件,并将要暴露服务的配置类配置如上图

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.example.demostarter.DemoConfig,\
  com.example.demostarter.DemoeConfig

4.mvn打包编译

mvn clean install -Dmaven.test.skip=true

5.发布到mvn中央仓库
6.A服务在pom中添加starter依赖

5.3 @SpringBootConfiguration

@Configuration是spring的注解
@SpringBootConfiguration:是springboot的注解;是一个特殊的configuration类

5.3 @ComponentScan

作用:扫描当前项目中需要注册到spring容器的bean
包括@Configuration @Component @Service @ Contorller @Repostriy @RestController等

6.rocket mq事务失败怎么处理

1.初次消费失败进入retry队列(重试队列)
2.最多重试18(默认16) 次后,依然失败则进入死信队列
3.在控制台查询出死信消息的topic
4.在消息列表查询具体的死信消息
5.在控制台选择消息重发(修改死信消息权限后)
6.依然失败需要程序员处理(如果是网络问题,网络恢复后重投;如果是代码bug问题,修复代码后重投入)

死信消息的权限是2:禁读;
死信消息权限:2-禁读;4-禁写;6-可读可写

死信队列具有如下的特性;
1.死信队列是一个特殊的topic,命名方式是%DLQ%comsumerGroupId
2.一个死信队列与一个消费组一一对应,而不是消费组的实例
3.一个消费组没有产生死信消息,那么不为为其创建死信队列
4.一个死信队列,包含了所有消费组的所有死信消息,不论该消息时属于那个topic

记录日志表通知开发人员处理

7.线程池为什么要添加一个没有任务的空线程

两种可能:
1.在创建线程池时,将核心线程池数量设置为0;导致阻塞队列中有任务缺不能立刻执行
2.线程池有个属性allowCoreTimeOut,允许核心线程回收断开,默认不允许;

线程池工作原理:
1.有任务时,当未达到核心线程数时,创建核心进程执行
2.当核心线程满了时,将任务放入阻塞队列
3.阻塞队列满了时,创建最大线程数
4.最大线程数满了时,执行拒绝策略
5.当最大线程有空闲时,会存活timealive时间 会被回收
6.核心线程数可以为0,但不会被回收

默认拒绝策略4种:
1.DiscardPolicy - 直接丢弃(可以做自定义的处理方式)
2.AbortPolicy-丢弃抛出异常(默认)
3.CallerRunsPolicy-使用当前线程去执行
4.DiscardOldestPolicy - 丢弃最早的任务,尝试重新执行任务(没获取到不做处理)

8.shareding jdbc 水平分表后如何聚合查询、范围查询

采用内存归并;其他查询场景用流式归并
范围分片算法RangeShardingAlgorithm
tablename_year_month

shareding jdbc工作流程
1.sql解析
2.执行器sql优化
3.sql路由
4.sql改写
5.sql执行
6.结果归并

9.jdk 1.8新特性

1.lambda表达式
2.函数式接口:Function接口,Comsumer等
3.optional对空指针处理
4.新增日期类的:ZoneId,LocalDate,LocalTime,LocalDateTime等
5.接口运行定义默认方法和静态方法
6.方法引用和构造方法引用;使用“::”
7.Stream流式操作

10.nginx配置优化

https://blog.csdn.net/qq_57377057/article/details/126568841

1.linux的ulimit配置
1.1 先设置linux的ulimit最大文件数
1.2 设置nginx work数和work最大连接数
2.cpu的亲和配置
能使nginx的work数绑定到cpu核心数上,减少切换
3.IO事件处理模型优化
多路复用器的设置,linux配置epoll
4.work_connnetction连接数优化
默认是1024,最大是65535
5.会话的保持时间(keepalive timeout)
长连接一般60s差不多了;根据不同的情况去调试
6.GZIP压缩性能优化
7.proxy超时设置
8.proxy_set_header(代理设置头信息等)
9.高效传输模式(sendfile on)
10.expires(到期)缓存调优
11.访问限流配置
12.内核参数优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值