int 和Integer的区别?

int是基本数据类型,Integer是java的一个类,里面封装了一些对int数据的操作或者对象之间的转换。(Integer对象里面也有缓存 (-128-127))

什么是自动装箱和自动拆箱?

自动装箱是基本数据类型转成对应的封装类,自动拆箱是封装类转成对应的基本数据类型。比如: int 转成Integer叫自动装箱,Integer转成int叫自动拆箱。

接下来看一下自动装箱和自动拆箱实现原理:

自动装箱:int转成Integer

方法的入参是Integer,调取这个方法时入参是int,程序依然可以运行。

看一下如下Case: 方法入参是Merchant,调取这个方法时入参是MerchantDetail,会报异常。那为什么int和Integer可以转换?MerchantDetail为什么不可以转成Merchant?

原理:

int与Integer之间的转换是编译器帮我们做的。 方法入参是Integer, 我们传入int 编译器会帮我们添加Integer.valueOf()这行代码。

自动拆箱:Integer转成int

方法入参是int 我们传入Integer 编译器会帮我们添加Integer.intValue()这行代码。写代码时不需要代码开发者去写转换逻辑,编译器发现需要转换他会帮我们完成这部分逻辑转换

你可能会好奇为什么编译器可以帮我们进行对象转换,

你写的是.java文件,编译器会将.java文件转成.class文件,编译器既然可以转换那么肯定可以识别你的代码。编译器在转换成.class文件的过程中,发现方法有int到Integer之间的转换,自动加上Integer.valueOf()这行代码。发现方法有Integer到int之间的转换,自动加上Integer.intValue()这行代码。

你写的代码只是你看到的代码,JVM真正运行的代码,是编译器转换后的代码,编译器会对你的代码进行优化和指令重排。

接下来看一下Integer缓存:

我们查看Integer.valueOf()里面的代码,可以看到Integer里面也使用了缓存 缓存的是-128~127的整形数据。我们可以从String和Integer代码设计中可以学到,可以添加缓存来提升程序性能

业务场景:很多页面都有外卖,超市便利等类目或者banner信息。

代码逻辑:

当需要查询类目数据时,从mysql中查询出需要展示的类目数据,用户的每一次页面请求,都需要请求一次mysql,流量低的时候没有问题,当流量高的时候,请求流量全部打到mysql,导致mysql宕机

业务特征: 这些类目数据不多,几乎是固定的数据,而且请求流量高,通过String和Integer的学习,我们可以将这部分数据放到内存当中

看一下代码:

先不考虑ArrayList线程安全问题。用户请求时,当categoryList里面没有数据的时候,查询数据库,然后将查询出来的数据放到内存中,下一次用户请求时,内存中有数据了直接返回。 性能提升的同时也防止了大量请求落到mysql。

看一下如下Case: 当类目数据没有在内存中时,需要查询数据库,查询耗时10ms。那这个间隙,因为数据没有在内存中,那流量也都落到了数据库中。又或者这个数据不是类目数据,而是某一个大网红数据,大网红开播短时间将有大量的粉丝涌入直播间,数据没有在内存中,查询数据库,将有大量的请求流量落到数据库层,那这个时间mysql就打挂了。

问题 ,因为数据没有在内存,大量请求会查询mysql数据 ,那加锁 ,让一个线程去mysql查询数据。

看一下代码:

当内存没有数据的时候,加锁只有一个线程可以从mysql读取数据。

问题:当流量非常高的时候会出现的问题:

1.锁的性能低 ,大量线程有加锁与释放锁逻辑,消耗系统资源;

2.从mysql加载数据到内存的间隙,因为数据没有在内存中,

大量的请求在内存中等待,内存和CPU的使用率不断升高,系统响应变慢的同时又需要处理大量的用户请求,直到服务宕机。

问题的根源是,当用户请求流量到达服务端时,服务端要快速的给用户返回数据。

接下来看一下代码:

在服务器启动的过程中,就将类目数据从mysql加载到内存中。 等你服务器起来后,可以对外提供服务, categoryList数据已经在内存中了。

系统应对高流量的一种方案:提前加载好几乎不变的数据到内存中。

这些数据几乎不变更,要是变更了,你又不想重新部署服务,可以将这部分数据放到动态配置中心里面,或者运行一个定时任务将mysql数据同步更新到内存中。

#大厂##面试题目#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务