java基础,没事的时候看一下

1、dataway了解一下
    前端直接写数据逻辑,不需要后端整理逻辑,引入jar有hasor,返回json格式的数据,相当于一个接口编辑容器。

2、springboot配置深入理解

3、jdk,jre,jvm   jdk包含了jre和jvm,jre里面包含了jvm,
   jdk与jre的区别,jdk是java开发的工具包,主要是面对开发人员,里面包含了编译器和jre,还有一些程序调试开发工具包,
   jre则是java的运行环境,里面包含了jvm以及java运行的包,只要安装了jre就可以运行java文件
   程序在执行之前先要把java代码转换成字节码(class文件),jvm首先需要把字节码通过一定的方式 类加载器(ClassLoader) 
   把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是jvm的一套指令集规范,并不能直接交个底层操作系统去执行,
   因此需要特定的命令解析器 执行引擎(Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行,
   而这个过程中需要调用其他语言的接口 本地库接口(Native Interface) 来实现整个程序的功能,这就是这4个主要组成部分的职责与功能。
   
4、java错误信息有哪些:NullPointerException、ArrayIndexOutOfBoundsException、FileNotFoundException、
                       NumberFormatException、SQLException、IOException、NoSuchMethodException
                       
5、java的编译过程:    双亲加载机制

6、java的基本类型:(byte,short,int,long数值类型),(float,double浮点),boolean(布尔),char(字节),void(java.lang包里面
                  的)
                  
7、java的调用顺序:静态方法->构造代码块(就是只有一个{}的模块)->构造方法->普通方法
                   若是有父类子类的话,父类静态方法->子类静态方法->父类构造代码块->父类构造方法->子类构造代码块->子类构造方法
                   ->普通方法(按照从上到下,从左到右依次执行)
                   简单而言:先把父类静态方法执行了再执行子类静态方法,然后把父类的构造代码块和构造方法执行完了之后,再执行子类的构造代码块和构造方法,
                   最后再按照代码顺序执行普通方法。不管是不是父类new子类,都是这样。
                   
8、引用类型有哪些:4种引用数据类型
                 (一)强引用:比如new的对象(实例对象),这种不会被gc回收,java虚拟机宁愿爆出OutOfMemeryError内存不足的错误,也不愿
                               强制回收这类对象的内存,
                 (二)软引用:当内存不足的时候会被释放内存空间
                 (三)弱引用:下一个周期会释放对象内存空间
                 (四)虚引用:随时都会释放对象内存空间

9、sql优化,尽量避免全表扫描,使用where和order by创建索引,尽量不要判空,判空会全表扫描,可以填写默认值的方式,少用!=的方式,
   以及<>的方式,以及in和not in,or,以及模糊查询。
   
10、nacos配置已经搞定:阿里巴巴的一个开源配置框架,先拉一个nacos项目下来,然后启动,然后在自己项目里面连接该nacos项目,具体的配置方式有相应文档记录。

11、java虚拟机的内部结构,jvm是java语言跨平台的桥梁,java的内存分配全部在虚拟机里面,内存包含了堆、栈、代码段、数据段。
    栈:基本数据类型的值、引用类型对象的指针、局部变量的值、保存加载方法时的帧。
    堆:new的对象,常量池。
    java虚拟机内部运行方式:变量值存在栈里面,会用指针指向堆里面的具体对象
    
    
12、jvm的内部结构:类加载器、内存区,执行引擎、本地库
    类加载器(ClassLoader)把.class文件引入到jvm里面,内部含有,方法区,栈,堆,程序计数器,本地方法栈,栈是跟线程相关联的,
    每多启动一个线程,内存里面就会开辟一个新的栈,一个栈里面有很多个桢,每一帧都是一个局部变量名称、方法返回值、
    用来记录变量名称以及基本数据,每一个方法的运行都是入帧和出帧的过程。
    栈和程序计数器是线程私有的,所谓线程私有,就是线程生就生,线程死就死,然后就不存在垃圾回收,只有方法区和堆里面的东西才是涉及到
    垃圾回收机制
    
13、垃圾检测和垃圾回收
    垃圾检测两种方法:
                    (一)引用计数法:给对象添加一个引用计数器,每当有个地方引用他,计数器就加一,没有引用就减一,任何时刻都为0的对象意味着这个对象没有被使用。
                    (二)可达性分析法:以根集对象为起始点进行搜索,当不可达的时候,说明该对象没有被引用。
                    根集对象GC roots的引用点:虚拟机栈,方法区中静态属性引用的对象,方法区常量引用对象,native方法
    垃圾回收:注意:gc只是回收对象内存,不是回收对象
            (一)标记清除,标记之后选定清除
            (二)复制,内存一分为二,只用一边的内存,把存活的对象复制到另一边,然后清除之前一边的内存
            (三)标记整理,这是结合了第一种和第二种方法,让内存更有规律
            (四)分代收集算法,以年龄形象的表达出来,年轻代->年老代->持久代
            年轻代有三个区,Eden,S0,S1,Eden是所有对象都会待的区域,一定周期之后,还存活的对象会经过S0和S1的复制方法之后,再
            经过几个周期还活着的话,就会转入年老区,年老区几个周期之后,当年老区经过几个周期之后当年老区内存被占满之后,就会触发
            Full GC 回收整个堆。
    
14、java的对象生命周期
    创建->引用->不可见(没有强引用的阶段)->不可达(跟集对象为起点进行搜索)->GC回收该对象的内存空间
    

    
15、线程的生命周期:新建--》就绪--》运行--》阻塞或者死亡
                    新建:就是刚使用new方法,new出来的线程;

                    就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;

                    运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;

                    阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;

                    销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;
    
    
    
15、索引就相当于目录标签,比如查一个人名,没有索引的话会全表扫描,但是如果该列有索引的话,会直接指定到这个名字上。
    
    组合索引如果要单独查询一个的话,单独查询前一个有效果,查询后一个没有效果。
    
    like模糊查询,如果只使用前面%会有索引效果,两个%的话,是没有索引效果的。
    
    
16、数据库存储时间,遇到时区转化问题的时候,用timeStamp,不用dateTime,timestamp会显示时分秒的具体值,dateTime不会,只会使用00来填充

17、transient 修饰字段不会被序列化

18、hashmap的底层原理:
                     一:hashcode是用来查找的,equals是用来比较两个对象是否相等的。hashcode适用于散列存储结构中确定对象的存储位置的。
                     对象的hashcode就是散列存储的位置,hashcode值相同的情况,对象不一定相同,只是表示两个对象在同一个篮子里面,还需要equals进行区分。
                     
                     当new一个HashMap的时候,就会创建一个Entry数组,每个Entry数组里面是一个链表,key-value的对象,Entry<key,value>
                     存储的时候,根据key的hash值,有一个hash算法算出的值,确定Entry数组的位置,但是存在当两个key的hash值相同的情况
                     (1)当key的hash值相同,就会再两个key用equals方法再次判断如果还是相同,那就进行覆盖value值
                     (2)当key的hash值相同,key的equals方法判断之后不同,那就把这个对象放进同一个Entry里面,只不过是先来的放前面,取的时候也是这样判断的。
                    二:
                    扩容:当数据存储超过75%的时候,就是0.75的比例,就直接扩容一倍。
                    
                    上面的是jdk1.7的版本:只有数组加链表结构。还容易导致闭环
                    
                    jdk1.8版本不一样了,是由:数组+链表+红黑树   
                    大致总结:(1)初始值还是16,增加因子一样是0.75 ,以2的幂数增加
                              (2)前面判断差不多,当hash碰撞的时候,链表里面数量超过8个的时候,后面插入的就会转换为红黑树
                              (3)低于6个时候,红黑树就会转换为链表结构,是所有的结构整体转换,所有中间存在一个7,作为一个临时转换点,不会让红黑树和链表一直转换。
                              (4)1.7采用的是尾插法,1.8采用的是头插法
                    
                    key为空的时候,怎么插入的?1.8与1.7差不多,都是把key为空的插入到table[0]
                    
                    
                    
                    
                    
                    
                     


19、hashmap与hashtable的区别:hashmap是线程不安全的,hashtable是线程安全的,所以hashmap性能好一点,hashmap的key可以为空,value也可以
    为空,hashtable不准key为空,hashmap的初始容量为16,hashtable的初始容量是11,填充默认因子都是0.75,hashmap扩容是当前容量翻倍
    hashtable则是扩容翻倍之后加一,hashmap继承的是AbstractMap抽象类,hashtable继承的是Dictionary抽象类,hashmap计算hash对key的hashcode
    进行二次hash,以获取更好的散列值,然后对table数组取模,hashtable计算hash是直接使用key的hashcode对数组的长度直接进行取模。
    
    hashmap确定数组位置的时候,是进行了二次hash,就是key值的hashcode会进行再次hash,以确定数组的位置。
    
20、修饰词:
           private:只能在改类访问
           protected:在该类或者子类或者同包里面访问
           public:所有的地方都能访问
           默认没写:只能在同包里面访问
    

21、callable的线程使用:callable是一个泛型,一个类实现callable接口,会重写call方法,返回泛型,运用FutrueTask<>也是泛型,得到返回值
                        了解返回情况。
                       例子:public class CallableTest<String> implements Callable<String>{
                                        
                                        @OverWrite
                                        public String call(){
                                            String result = "执行成功";
                                            return result;
                                        }
                       
                            }
                            
                            
                            
                            class Test{
                                public static void main(String[] arges){
                                    
                                    CallableTest<String> test = new CallableTest<>();
                                    FutureTask<String> f = new FutureTask<String>(test);
                                    new Thread(f).start();      这一步就是执行线程
                                    System.out.print(f.get());  这一步就是打印线程执行结果的    
                                
                                }
                            
                            }
                            
22、线程的join方法,是等待该线程执行完成之后,再执行主线程。


23、基本类型和封装类会自动转换。比如int会自动转为Integer

23、docker的讲解:安装在centos上面
                docker是一个应用容器引擎,docker并不是虚拟机,没有底层的操作系统,不能完全隔离系统,但是便于隔离各个应用(后端,前端,测试)
                docker分为三个部分:
                                  仓库:用于存放镜像文件的仓库
                                  镜像:构建docker容器的源代码
                                  容器:docker镜像创建的运行实例
                
                查看是否安装了docker命令:docker -v
                命令:systemctl start docker 启动docker
                      systemctl restart docker   重启docker
                      systemctl stop docker  停止docker
                      docker search mysql 搜索镜像


                
24、开发微信小程序教程    


25、spring的注解有什么作用:
                       

           每个的用处,如何书写注解:
                                                 


26、rabbitMQ的详解:
                  
27、Nginx的运用:

28、jdk源码:


29、把代码上传到github上面

30、Swagger:接口文档集成,相对简便的书写接口文档


31、http请求get和post的区别


32、微信小程序构建:

33、接口里面方法默认的就是public,因为接口是对外提供服务的,就是不清楚外部的使用情况,所以就是public一切交给外部


34、切面aop编程,使用aspect注解,方法上面有切入点pointCut("切入点"),再使用around的注解然后开始实现逻辑。


35、arraylist和linkedlist的区别:arraylist底层是数组,linkedlist是双向链表结构,总体上来讲的话,当任意位置增加或者删除元素的话,arraylist性能就不如linkedlist


36、concurrentHashmap运用场景:分段式锁,高并发状态能很好的实施。
                              (1)一个entry对象里面加上链表结构就是一个bucket(桶),ConcurrentHashMap里面不只有链表,还有红黑树(提高查找效率)
                              (2)在JDK1.8中进行对HashMap优化的时候,把链表转化为红黑树的阈值是8
                                如果选择6和8(如果链表小于等于6树还原转为链表,大于等于8转为树),中间有个差值7可以有效防止链表和树频繁转换。假设一下,如果设计成链表个数超过8则链表转换成树结构,
                                链表个数小于8则树结构转换成链表,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低。
                                还有一点重要的就是由于treenodes的大小大约是常规节点的两倍,因此我们仅在容器包含足够的节点以保证使用时才使用它们,当它们变得太小(由于移除或调整大小)时,
                                它们会被转换回普通的node节点,容器中节点分布在hash桶中的频率遵循泊松分布,桶的长度超过8的概率非常非常小。所以作者应该是根据概率统计而选择了8作为阀值

37、sdk的访问者模式:bean工厂注入,一个接口不同实现类,根据bean注入的名称

38、finalize()方法:是对象被回收之前会调用一次该方法,因为会被调用一次,所以可以让对象重新活一次。

39、pl/sql是什么:PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。

40、存储过程和函数的区别:函数可以在sql里面调用,存储过程可以返回参数并且可以多个,函数只能返回一个具体值或者表对象

41、mydql集群搭建:

42、mysql的分表和分区:
                     (1)mysql集群,涉及到分表,减少sql查询等待时间。
                     (2)建立多张同类型表,根据一个字段来判断存储在哪一张表上面。
                     (3)marge合并:mysql> CREATE TABLE IF NOT EXISTS `alluser` (  
                                    `id` int(11) NOT NULL AUTO_INCREMENT,  
                                    `name` varchar(50) DEFAULT NULL,  
                                    `sex` int(1) NOT NULL DEFAULT '0',  
                                    INDEX(id)  
                                    ) TYPE=MERGE UNION=(user1,user2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ;   //这里把一表和二表存储进去,实现合并的功能
 
                     
CREATE TABLE IF NOT EXISTS `alluser` (  
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `age` int(10) NOT NULL,
  `memo` varchar(32) NOT NULL,
  PRIMARY KEY (`id`), 
) engine = merge union=(user1,user2) insert_method = last auto_increment=1 default charset=utf8;                     
                     
                     
nacos配置
SQL优化
jdk和jre的区别
==和equals的区别,equals对比对象的结果?双等号是基本数据类型的判断,也可以判断引用类型,但是引用类型的就要引用指向同一个才会返回true,equals底层就是双等号判断,只不过重写了一些引用类型,让equals去判断值相等了,equals也可以判断基本类型。
hashcode相同,equals不一定为true,理由待定。
final的作用,修饰常量,常量必须初始化,初始化值不能被修改,修饰方法,方法不能重写,修饰类,类不能被继承。
Math.round()是什么方法?
能操作字符串的对象有哪些?string,stringbuffer,stringbuilder,string是声明不可变的对象,stringbuffer和stringbuilder是可以变的,stringbuffer是线程安全的,stringbuilder是线程不安全的,但是stringbuilder性能要高于stringbuffer,所以单线程的情况建议使用stringbuilder。
虚拟机的内部结构是什么?
string的方法有哪些,indexof()指定字符的索引,chartat()指定索引的字符,length()字符长度,tolowercase,touppercase大小写转换,trim()去空格,split()分割,getbyte()字符数组,substring()截取,replace()替换,equals()比较值。
字符串的反转方法,stringbuffer或者stringbuilder的reverse方法。
抽象类必须要用抽象方法吗?不是的。要测试一下?
抽象类的特点,抽象类不能实例,抽象类里面可以有抽象方法。
抽象类就是为了继承的。
接口和抽象类的区别,抽象类是继承,接口是实现,一个类只能继承一个抽象类,但是可以实现很多个接口。
Java的io流有哪些?按照功能来区分是输入流和输出流,按照类型来分就是字节流和字符流。
bio,nio,aio的区别?
files的常用方法,exists()检查文件是否存在,
createfile()创建文件,createdirectory()创建文件夹,read()读取文件,write()写文件,size()文件大小,copy()文件复制,delete()删除,move()文件移动。


容器
collection和collections的区别,collection是集合的顶级接口,collections是一些静态方法,可以排序,搜索以及线程安全这些。
hashmap和hashtable区别,hashmap是线程不安全的效率要高些,hashtable是线程安全的。hashmap允许空键值,hashtable不允许。
hashmap与treemap的选择,hashmap添加和删除和修改要好一点,treemap偏向于有序排序。

hashmap的原理,麻蛋必考题,日,

hashset的原理,hashset底层是hashmap,只不过hashset只取了hashmap的key值,value值都设置为PRESENT。

arraylist和linklist的区别,arraylist底层是数组支持随机访问,linklist是双向链表结构不支持随机访问。

如何实现数组和list的转换,list转换为数组调用arraylist的toarray方法,数组转换为list调用arrays的aslist方法。

array和arraylist的区别,array有固定长度,arraylist没有固定长度,array是arraylist的底层,array可容纳基本类型和对象,arraylist只能存对象。

内存,堆,栈的区别?

queue的poll()和remove()方法区别,两者都是从队列里面取一个元素,poll取不到的时候会返回空,但是remove()则会报错。

迭代器了解一下?

多线程
并行和并发的区别,并行是两个或者多个事件同一时刻发生,并发是两个或多个事件同一时间间隔发生,并行是不同实体上的多个事件,并发是同个实体上面的多个事件。

docker的配置使用?

进程和线程的区别,一个程序的运行至少有一个进程,一个进程至少有一个线程。

创建线程的有几个方式,三个,一个继承thread对象重写run方法,线程启动是start方法,一个是实现runnable接口重写run方法,线程启动是start方法,通过callable和future创建线程。

创建线程的方法有哪些?callable和future创建线程的方式?

runnable和callable的区别,runnable是重写run方法,没有返回值,只是执行run方法里面的代码,callable是实现call方法,有返回值,返回值是一个泛型,和future,futuretask配合处理异步执行结果。                 
                     
进程:是cpu运行调度的基本单位,一个进程可以有多个线程,就叫做多线程

线程池: java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池,先启动若干数量的线程,并让这些线程都处于睡眠状态,
         当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。        
        线程池包括核心线程数,阻塞队列,最大线程数三个核心要素。请求过来之后,先判断核心池的线程数有没有超过所设置的数目,如果有,则放入阻塞队列,
        如果阻塞队列也放满了,那么直接开启新的线程,直到最大线程数目,到达最大线程数目之后,线程池就会拒绝
                     
数据库连接池:数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个,数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,
              并将这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库联接对象),由应用程序动态地对池中的连接进行申请、使用和释放
              对于多于连接池中连接数的并发请求,应该在请求队列中排队等待
                     
 高并发解决思路:减少数据库压力

(1)分布式数据库:主从复制、读写分离、负载均衡(M-S或者M-M-S)。M-M-S模式中两个M只有一个是处于Active状态的,当处于Active态的数据库服务器崩溃的时候,
    另一个M快速替代。这种方式也可以使用哨兵模式进行操作。在使用数据库主从复制的过程中,当某一个表数据量过大的时候,也会造成数据库效率的下降,此时,我们可以使用库表散列对其进行调优。
(2)数据库缓存:使用Redis做数据库缓存
(3)数据库连接池
(4)数据库索引
(5)数据库集群
库表散列:不同模块对应不同的数据库或者表,再按照一定的策略,对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列。

java实现hash计算的方法:太多了,hash是一种总称,太多算法。

MD5算法:    


session:(1)是服务器端生成的保存在服务器端的一个会话标志。
         (2)session类似与键值对存储
         (3)session的作用:http协议是无状态的,就是http请求之间是没有关联的,一个页面请求跟另一个页面请求是没有关联的,然后cookie就诞生了,但是cookie存储数量少,而且在客户端,会被串改
                            于是session 诞生了,从上面的描述来讲,它就是在一次会话中解决2次HTTP的请求的关联,让它们产生联系,让2两个页面都能读取到找个这个全局的session信息。
                            session信息存在于服务器端,所以也就很好的解决了安全问题。
        
ipv6与ipv4的区别:
                v6是128位,v4是32位的(全球一共可以有大概40亿个ip地址,还要内网专用的),但是v6就相当于40亿的4次方了,基本上可以满足每台灯都可以分配一个ip,以后每张身份证必会绑定一个ip
                v6更安全,更难破译
                

yml与properties的区别:正常的情况是先加载yml,接下来加载properties文件。如果相同的配置存在于两个文件中。最后会使用properties中的配置。最后读取的优先集最高


glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc

centos与ubuntu的区别:
                    (1)对于服务器操作系统来说,并不需要太多的应用程序,需要的是稳定,操作方便,维护简单的系统,因此,非常多的商业公司部署在生产环境上的服务器都是使用CentOS系统。
                    (2)对于个人使用来说,Ubuntu系统有着靓丽的用户界面,完善的包管理系统,强大的软件源支持,丰富的技术社区,并且对计算机硬件的支持优于centos,兼容性强。可以选择ubuntu。

@EnableAutoConfiguration的注解用处:            
                                    其中最关键的要属@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以
                                    帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。

    


要使用Java SPI,需要遵循如下约定:
1、当服务提供者提供了接口的一种具体实现后,在jar包的META-INF/services目录下创建一个以“接口全限定名”为命名的文件,内容为实现类的全限定名;
2、接口实现类所在的jar包放在主程序的classpath中;
3、主程序通过java.util.ServiceLoder动态装载实现模块,它通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,把类加载到JVM;
4、SPI的实现类必须携带一个不带参数的构造方法;


Java中有两个Date类,一个是java.util.Date,通常情况下用它获取当前时间,另一个是java.sql.Date,是针对SQL语句使用的,它只包含日期而没有时间部分。


192.168.11.2

cd /etc/sysconfig/network-scripts/
vi  第一个

                  
配置虚拟机的时候配置固定ip    
BOOTPROTO=static        #开机协议,有dhcp及static;
ONBOOT=yes              #设置为开机启动;
      
DNS1=114.114.114.114
IPADDR=192.168.11.129
NETMASK=255.255.255.0
GATEWAY=192.168.11.2

重启网络
service network restart


线程池:
ThreadPoolTaskExecutor
线程是一个操作系统级别的概念。JAVA语言(包括其他编程语言)本身不创建线程;而是调用操作系统层提供的接口创建、控制、销毁线程实例

设置线程的个数:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

      比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32

      进一步转化:最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目


TreadPoolExecutor将根据corePoolSize和maximumPoolSize设置的边界自动调整池大小。当新任务在方法execute(java.lang.Runnable)中提交时,
如果运行的线程少于corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于corePoolSize而少于maximumPoolSize,
则仅当队列满时才创建新的线程。如果设置的corePoolSize和maximumPoolSize相同,则创建了固定大小的线程池。
如果将maximumPoolSize设置为基本的无界值(如Integer.MAX_VALUE),则允许线程池适应任意数量的并发任务。

简单点就是:当现有线程数小于corePoolSize,那新开个线程,线程池都会新增一个线程,直到等于corePoolSize。

如果池中当前有多于corePoolSize的线程,则这些多出的线程在空闲时间超过keepAliveTime时将会终止。
如果运行的线程少于corePoolSize,则Executor始终首选添加新的线程,而不进行排队。
如果运行的线程等于或多于corePoolSize,则Executor始终首选将请求加入队列,而不添加新的线程。

线程池只会回收非核心线程,而核心线程是不会回收的。
有三种线程方式:继承Thread、实现Runable、实现Callable<>
        
        @Resource(name = "selfTask")
        private ThreadPoolTaskExecutor executor;

        Future<User> future = executor.submit(new Callable<User>() {
            @Override
            public User call() throws Exception {
                User user = new User();
                user.setUserId("211111");
                user.setId(123);
                user.setRoleCode("131");
                user.setUserName("刘德华");
                return user;
            }
        });
        
        这种方式没有用到过,简单来说就是开启线程之后,需要有返回值的就是用这种情况。
        
FixedThreadPool是一个有固定核心线程数的线程池,且这些核心线程不会被回收。当线程数超过corePoolSize时,就把任务存进任务队列。若线程池有空闲线程,就去任务队列中取任务。

CachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。


Lock接口和synchronized不同
(1)Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁.
(2)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
(3)lock只能在try catch里面实现,而且解锁的方式必须写在finally里面,lock是一定要释放锁的,不然会导致死锁。lock针对的是线程。


java是的类是单继承的,但是接口却是多继承的(只能继承接口)。jdk1.8的版本接口是可以书写默认方法的,如果父类也有这个方法,则需要要求重写。
注意:若是多个父接口都有同样的方法,必须保证每个父接口的返回值一致


单例模式:懒汉、饿汉、静态内部类、双重锁、枚举

构造代码块的作用:
                有用的,对象实例化的时候构造代码块都会执行,而有多个构造方法时,每个构造方法都不一定会被执行。
                如果只有一个构造方法,那么构造代码块写在构造方法里也可以,但如果有多个构造方法需要做一部分公共的处理,
                那么这部分公共的代码可以提取出来放在构造代码块中,这样就可以只写一次,避免代码重复。
                
                构造代码块是用来初始化的,初始化不同对象的共同初始化内容

单点登录:
        多个系统,使用同一套认证系统,所有应用系统的登录和注册都是跳转到认证系统,当用户登录之后,认证系统会返回一个唯一标志,当用户拿着这个唯一标志就可以进入各个应用系统。
        每个应用系统会拿着唯一标志去认证系统获取用户信息。
        
        认证系统需要做的事情:
                            生成用户唯一标志并返回给用户。
                            保证用户唯一标志的有效性。
                            

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值