JAVA面经复习(二十四) 面试难度:☆☆☆

面试难度:☆☆☆
声明:答案均为网上搜索汇总得到的参考答案,如有不妥或意见相左之处欢迎指出!

问:介绍一下怎么防止发生超卖

答: 1、采用redis队列,将要促销的商品数量以队列的方式存入 redis 中,每当用户抢到一件促销商品则从队列中删除一个数据,确保商品不会超卖。2、使用文件锁实现。当用户抢到一件促销商品后先触发文件锁,防止其他用户进入,该用户抢到促销品后再解开文件锁,放其他用户进行操作。3、 mysql 的事务加排他锁,其对数据库的性能要求较大。

问:实现多线程的方式

答: 1、继承Thread类;2、实现Runnable接口;3、实现Callable接口(实现的call()方法相比run()方法,可以返回值;方法可以抛出异常;支持泛型的返回值;需要借助FutureTask类,比如获取返回结果);4、使用线程池的方式。

问:线程池的7大参数?

答:1、 corePoolSize,线程池核心线程数;

2、maximumPoolSize,最大线程数;

3、keepAliveTime,存活时间;

4、unit,空闲线程存活时间单位;

5、workQueue,阻塞队列;

6、threadFactory,线程工厂;

7、handler,拒绝策略;

问:介绍一下Redis?

答: redis是一个完全开源的、高性能的 key-value 数据库,其支持数据持久化和数据备份,常用做缓存来减轻数据库的压力。

问:你知道缓存锁吗 ?

答:缓存锁是为了避免多个cpu缓存同时修改主存里同一个缓存行引起的并发修改问题。举例cpu缓存都修改了同一个缓存行的数据,此时多个cpu都要求把自己的数据要同步到主存,这就存在并发修改数据的问题,所以只能加锁,一个个来。

问:Redis的数据类型?

答:redis的数据结构包括Set,Zset,Hash,List,String五种。

问:Redis的缓存雪崩、缓存击穿和缓存穿透 ?

答:缓存雪崩指的是多数信息在同一时间失效,致使许多请求打到数据库上。缓存击穿是指,缓存中的数据由于到期失效,使得原本查询缓存的请求打到了数据库。缓存穿透,则是指缓存中和数据库中都没有该数据,而用户不断的发起请求。

问:讲一下hashmap

答:hashmap数据结构在JDK1.8中采用数组+链表/红黑树的结构,当链表达到一定长度(8个)的时候,会为了加快检索的速度转换成红黑树。其put的流程大致为采用.hashCode()的方法首先获取一个对应的hash值,再对这个hash值进行一次哈希操作,找到对应的数组下标,这个时候判断是链表还是红黑树,采用对应的方法进行遍历。get()方法则类似。当插入后,如果数组的元素达到了负载因子的上限12个,那么就启动resize的方法,将当前的数组扩充两倍,并转移数据。

问:java8之后为什么引入元空间?

答:1、字符串存在永久代中,容易出现性能问题和内存溢出。
2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出,元空间允许自定义大小,从而减少了OOM的错误。
3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低
4、将 HotSpot 与 JRockit 合二为一。

问:要读取几千万条数据,给你3台4核8G的处理器,让你设计一个多线程去读,核心线程数怎么设计,依据是什么?拒绝策略怎么选择,为什么?

答:核心线程数的设计和任务的类型有直接关系。

1、CPU密集型:核心线程数 = CPU核数 + 1;这种情况是为了线程池能最大程度的使用CPU的核数,同时多出的一个线程可以用于IO操作。

2、IO密集型:核心线程数 = CPU核数 * 2;IO密集型则大多数时间花费在IO上,因此线程理论上是越多越好,考虑到实际情况一般采用2倍的CPU核心数即可。

拒绝策略有四种如下:

1、AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。-----------(默认策略)推荐是对比较关键的任务使用,以便排查。

2、DiscardPolicy:丢弃任务,但是不抛出异常。 通常对一些无关紧要的任务采用该策略。

3、DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。 一方面要判断实际的业务是否允许抛弃老任务,另一方面可能对于一些对任务时限有要求的任务可以采用。

4、CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务。

参考资料:

京东Java开发一面面经

电商中怎么防止超卖问题