java 知识点突击-(101-110)

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 知识点突击-(101-110)相关的知识,希望对你有一定的参考价值。

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


java 知识点扫盲目录

https://blog.csdn.net/weixin_38316697/article/details/121991582

java 知识点突击-(101-110)

101 redis集群方案?

1、主从模式
2、哨兵模式
主要一些功能:
1)、集群监控:负责监控redis 主节点和从节点进程是否正常工作;
2)、消息通知:如果某个redis实例出现故障,那么哨兵负责发送报警信息给管理员
即使部分哨兵节点挂掉,哨兵集群还是可以正常工作。
3)、故障转移:如果主节点挂掉,会自动转移到从节点;
故障转移时,判断主节点是否宕机需要大部分的哨兵都同意才行,涉及到分布式选举。
4)、配置中心:如果故障转移了,通知client客户端新的地址;

注:
1)、哨兵通常需要三个实例来保证自己的健壮性。
2)、哨兵+redis主从部署架构,是不保证数据丢失的,只能保证redis集群高可用性。
3)、对于哨兵+redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。
3、redis Cluster模式
4、redis Sharding模式


102 redis主从复制原理?

most 节点可读可写、从节点只读,从节点的数据来源从most节点获取,主从复制就是将most节点的数据复制到从节点

1、全量复制:
1)主节点通过bgsave命令fork一个子进程进行RDB持久化;
2)主节点通过网络传输将RDB文件传给子节点;
3)从节点清空数据,加载RDB文件,加载过程中是阻塞的,无法响应客户端命令,如果从节点执行AOF(存储每一条操作记录,类似于mysql的binlog);
2、增量复制:
1)复制偏移量:
主从节点分别维护一个偏移量offset;
2)复制挤压缓存区,主节点维护了一个固定长度的先进先出的队列,将offse放入队列中,当主从节点offset的差距过大超过队列长度时,无法执行增量复制,只能进行全量复制;


103 对象入set要注意什么?

保证该集合的元素唯一性。
通过对象的hashCode和equals方法来完成对象唯一性的。

  如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
  如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
  如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

104 spring的BeanFactory和FactoryBean有什么区别?

BeanFactory是一个Factory,也就是IOC容器或对象工厂,FactoryBean 是个bean,在spring中所有的Bean都是BeanFactory(IOC容器)来进行管理,但对FactoryBean而言,这个bean不是简单的bean,而是一个
能生产或者修饰对象生产的工厂bean,它的实现与设计模式中的工厂模式和修饰者模式类似


105 String 在内存中所占的内存大小?

空String对象所占用的内存空间:

对象头(8 字节)+ 引用 (4 字节 )  + char 数组(16 字节)+ 1个 int(4字节)+ 1个long(8字节)= 40 字节

非空String占用的空间:

40 + 2 * n
其中n为字符串的长度

106 抽象类能使用 final 修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类。


107 常用的四种线程池?

107::01 newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
优点:
1、工作线程的创建数量几乎没有限制
2、长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),
则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
缺点:
一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪(重点)。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


      public static void main(String[] args) 
            ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) 
                      final int index = i;
                      try 
                      Thread.sleep(index * 1000);
                     catch (InterruptedException e) 
                      e.printStackTrace();
                      
                     cachedThreadPool.execute(new Runnable() 
                       public void run() 
                        System.out.println(index);
                       
                      );
                     
      

107::02 newFixedThreadPool

指定工作线程数量的线程池,每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
优点:
它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。
缺点:
在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public static void main(String[] args) 
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
            for (int i = 0; i < 10; i++) 
                     final int index = i;
                     fixedThreadPool.execute(new Runnable() 
                      public void run() 
                       try 
                        System.out.println(index);
                        Thread.sleep(2000);
                        catch (InterruptedException e) 
                        e.printStackTrace();
                       
                      
                     );
                    
      

107::03 newSingleThreadExecutor

创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
如果这个线程异常结束,会有另一个取代它,保证顺序执行

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public static void main(String[] args)
            // TODO Auto-generated method stub
            ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
            for (int i = 0; i < 10; i++) 
                     final int index = i;
                     singleThreadExecutor.execute(new Runnable() 
                      public void run() 
                       try 
                        System.out.println(index);
                        Thread.sleep(2000);
                        catch (InterruptedException e) 
                        e.printStackTrace();
                       
                      
                     );
                    
      

107::04 newScheduleThreadPool

创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。

public static void main(String[] args) 
            //延迟3秒执行
            ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
              scheduledThreadPool.schedule(new Runnable() 
               public void run() 
                System.out.println("delay 3 seconds");
               
              , 3, TimeUnit.SECONDS);
             //表示延迟1秒后每3秒执行一次
              ScheduledExecutorService scheduledThreadPool1 = Executors.newScheduledThreadPool(5);
              scheduledThreadPool1.scheduleAtFixedRate(new Runnable() 
               public void run() 
                System.out.println("delay 1 seconds, and excute every 3 seconds");
               
              , 1, 3, TimeUnit.SECONDS);


108 说一下线程池的参数都有哪些?

ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

108::01 corePoolSize:核心线程数量

线程池核心线程数量,核心线程不会被回收,即使没有任务执行,也会保持空闲状态
线程池内部核心线程数量,如果线程池收到任务,且线程池内部线程数量没有达到corePoolSize,线程池会直接给此任务创建一个新线程来处理此任务。

常驻线程,随着线程池的存在而存在,核心线程数最终的回收是随着线程池的回收而回收

108::02 maximumPoolSize:最大允许线程数量

池允许最大的线程数,【当线程数量达到corePoolSize,且workQueue队列塞满任务了之后】,继续创建线程
用处:
线程池内部线程数量已经达到核心线程数量,即corePoolSize,并且任务队列已满,此时如果继续有任务被提交,将判断线程池内部线程总数是否达到maximumPoolSize,如果小于maximumPoolSize,将继续使用线程工厂创建新线程。如果线程池内线程数量等于maximumPoolSize,就不会继续创建线程,将触发拒绝策略RejectedExecutionHandler。新创建的同样是一个Work对象,并最终放入workers集合中。

108::03 keepAliveTime、unit 超出线程的存活时间

超过corePoolSize之后的“临时线程”的存活时间
当线程池内部的线程数量大于corePoolSize,则多出来的线程会在keepAliveTime时间之后销毁。
unit:单位

108::04 workQueue 任务队列

线程池需要执行的任务的队列,通常有固定数量的ArrayBlockingQueue,无限制的LinkedBlockingQueue。

108::05 threadFactory 线程工厂,用于创建线程

当前线程数超过corePoolSize时,新的任务会处在等待状态,并存在workQueue中。
线程池内初初始没有线程,任务来了之后,会使用线程工厂创建线程。

108::06 handler 任务拒绝策略

当任务队列已满,又有新的任务进来时,会回调此接口。有几种默认实现,通常建议根据具体业务来自行实现。

举例:

现有一个线程池,参数corePoolSize = 5,maximumPoolSize = 10,BlockingQueue阻塞队列长度为5,此时有4个任务同时进来,问:线程池会创建几条线程?
如果4个任务还没处理完,这时又同时进来2个任务,问:线程池又会创建几条线程还是不会创建?
如果前面6个任务还是没有处理完,这时又同时进来5个任务,问:线程池又会创建几条线程还是不会创建?

解答:

线程池corePoolSize=5,线程初始化时不会自动创建线程,所以当有4个任务同时进来时,执行execute方法会新建【4】条线程来执行任务;
前面的4个任务都没完成,现在又进来2个队列,会新建【1】条线程来执行任务,这时poolSize=corePoolSize,还剩下1个任务,线程池会将剩下这个任务塞进阻塞队列中,等待空闲线程执行;
如果前面6个任务还是没有处理完,这时又同时进来了5个任务,此时还没有空闲线程来执行新来的任务,所以线程池继续将这5个任务塞进阻塞队列,但发现阻塞队列已经满了,核心线程也用完了,还剩下1个任务不知道如何是好,于是线程池只能创建【1】条“临时”线程来执行这个任务了;
这里创建的线程用“临时”来描述还是因为它们不会长期存在于线程池,它们的存活时间为keepAliveTime,此后线程池会维持最少corePoolSize数量的线程。


109 创建线程有哪几种方式?

1、继承Thread类创建线程类,定义Thread类的子类,并重写该类的run方法
创建Thread子类的实例,即创建了线程对象。
调用线程对象的start()方法来启动该线程。
2.通过Runnable接口创建线程类
定义runnable接口的实现类,并重写该接口的run()方法,、
3. 通过Callable和Future创建线程


110 线程池中submit()和execute()方法有什么区别?

接收的参数不一样
submit有返回值,而execute没有
submit方便Exception处理


创作不易、点关注、不迷路

点击主页、更精彩 !!!

以上是关于java 知识点突击-(101-110)的主要内容,如果未能解决你的问题,请参考以下文章

java 知识点突击-(121-130)

java 知识点突击-(171-180)

java 知识点突击-(161-170)

java 面试知识点突击-(61-70)

java 知识点突击-(111-120)

java 面试知识点突击-(41-50)