JAVA面经复习(二十四)面试难度:☆☆☆
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:由调用线程(提交任务的线程)处理该任务。