1.访问修饰符public,private,protected,以及不写(默认)时的区别?
修饰符 | 当前类 | 同包 | 子类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | x |
default | √ | √ | x | x |
private | √ | x | x | x |
类成员不写修饰符默认为default,私有的只能当前类,public所有类,protected可以子类对不是同一包中的没有父子关系的类相当于私有,default默认对不同包不行
2.int和Integer有什么区别?
首先int是基本类型之一,integer是包装类是对象,而且有缓存对于-128-127之间,
-
原始类型: boolean,char,byte,short,int,long,float,double
-
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
3.String和StringBuilder、StringBuffer的区别?
它们可以储存和操作字符串。其中String是只读字符串,它的底层是final修饰过的,如果修改值,那么会返回一个新地址,从而证明不能修改原来的,所以不可变
StringBuffer,有synchronized修饰 StringBuilder没有,所以单线程下我们都使用StringBuilder提高效率,而且String的+号其实是也是new的一个StringBuilder利用append然后拼接的返回的toString();
4.HashMap的⻓度为什么是2的幂次⽅?
-
通过将Key的hash值与length-1进⾏&运算,实现了当前Key的定位,2的幂次⽅可以减少冲突(碰撞)的次数,提⾼HashMap查询效率
-
如果length为2的次幂 则length-1 转化为⼆进制必定是11111……的形式,在于h的⼆进制与操作效率会⾮常的快,⽽且空间不浪费;如果length不是2的次幂,⽐如length为15,则length-1为14,对应的⼆进制为1110,在于h与操作,最后⼀位都为0,⽽0001,0011,0101,1001,1011,0111,1101这⼏个位置永远都不能存放元素了,空间浪费相当⼤,更糟的是这种情况中,数组可以使⽤的位置⽐数组⻓度⼩了很多,这意味着进⼀步增加了碰撞的⼏率,减慢了查询的效率!这样就会造成空间的浪费。
5.Comparable接⼝和Comparator接⼝有什么区别?
Comparable: 内部比较器,一个类如果想要使用 Collections.sort(list) 方法进行排序,则需要实现该接口
Comparator: 外部比较器, 用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意进行排序.无需改变类的结构,更加灵活。可以重写compareTo方法进行重写排序的规则
实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改
public class PersonComparator implements Comparator<Person> {
//排序算法,自己实现排序逻辑
@Override
public int compare(Person o1, Person o2) {
//因为Person对象的age属性使Integer类型的,Integer实现了Comparable接口,实现了compareTo方法
return o1.getAge().compareTo(o2.getAge());
}
}
6.Class.forName的作⽤?为什么要用
它实际是用指定的全限定类名字符串去寻找该类,如果该类被加载过,直接返回该字节码实例对象,否则的话双亲委派机制一层一层的找,如果都找不到就会报错ClassNoFound,。加载完这个Class字节码后,接着就可以使⽤Class字节码的newInstance⽅法去创建该类的实例对象了。
实际上就是反射,我们可以动态得到一个类的信息,而且很多类都是编译器才知道的,需要动态的去加载类,就需要知道类名,这时候就需要使⽤Class.forName去动态加载该类,这个类名通常是在配置⽂件中配置的,
例如,spring的ioc中每次依赖注⼊的具体类就是这样配置的在spring-factories中就有许多类名,jdbc的驱动类名通常也是通过配置⽂件来配置的,以便在产品交付使⽤后不⽤修改源程序就可以更换驱动类
7. Mysql中有哪⼏种锁?
MyISAM⽀持表锁,InnoDB⽀持表锁和⾏锁,默认为⾏锁,还有读写锁,排他锁for update
表级锁:开销⼩,加锁快,不会出现死锁。锁定粒度⼤,发⽣锁冲突的概率最⾼,并发量最低
⾏级锁:开销⼤,加锁慢,会出现死锁。锁⼒度⼩,发⽣锁冲突的概率⼩,并发度最⾼
8.并行和并发的区别?
并发:一个处理器可以同时处理多个任务。这是逻辑上的同时发生。
并行:多个处理器同时处理多个不同的任务。这是物理上的同时发生。
有一个清晰地比喻:
并发:一个人同时吃三个苹果。并行:三个人同时吃三个苹果。
9.多线程和单线程的区别和联系
并不是单线程一定比多线程慢,两者没有绝对的,得根据电脑cpu处理器等还有处理机制
- 在单核cpu中,cpu分为很多很小得时间片,每一个时刻一个线程在执行,是一种微观上轮流占用cpu得机制,看起来在并行,实质是时间片短,下一个紧接着处理所以会容易看成并行
- 多线程的话,因为存在线程上下文切换,甚至要切换为内核态再回到用户态,会导致执行效率变慢,所以一个拥有两个线程的进程执行的时间会比一个线程执行两次的进程长
多线程不会提高程序的执行速度,但是会减少用户的响应时间,提高用户体验感
10.什么是bean的自动装配?
再说自动装配之前,我们先聊一聊什么是手动装配。
手动装配就是我们在先前讲的那些,要自己给定属性,然后赋值
Spring IOC容器可以自动装配Bean,需要做的仅仅实在的autowire属性里指定自动装配的模式
byType(根据类型自动装配):若IOC容器中有多个与目标Bean类型一致的Bean。在这种情况下,Spring将无法判断哪个Bean最合适该属性,所以不能执行自动配置。
byName(根据名称自动装配):必须将目标Bean的名称和属性名设置的完全相同。
constructor(通过构造器自动装配):当Bean中存在多个构造器时,此种自动装配方式会很复杂,不推荐使用
注解的话还可以通過@AutoWire或者@Resource進行自動裝配,前者按名字,后者按类型