1. Java中的四种引用:
1.1 强引用(Strong Reference):
最常见的普通对象引用,如果有强引用就证明这个对象还活着.这样同样也可以确定 当我们想要垃圾回收装置将无用的对象回收的时候,只要将引用赋值为null就可以了.
1.2 软引用(Sort Reference):
被软引用引用的对象,如果当jvm内存不足的时候会清理掉.
SoftReference<String> sr= new SoftReference(new String("hello"));软引用通常配合引用队列向使用.
1.3 弱引用(WeakReference):
弱引用更弱,不能豁免垃圾收集,有就用没有就只好重现实例化.
WeakReference sr = new WeakReference(new String("hello"));
1.4 幻想引用(PhantomReference):
不能通过他访问对象,仅仅是能提供确保对象呗finalize以后做某些事的机制.
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);
如何声明对象强可达?
java.lang.ref.Reference类的static void reachabilityFence(Object ref)方法.可以标记对象强可达.
2. 什么叫做Immutable 类?
就是不可变类,如果改变就是创建了一个新对象,String就是这种类.
创建一个Immutable 类,首先类需要被final 修饰,属性不能提供set方法,属性也要私有并且被final修饰,大致规则如下
1)immutable对象的状态在创建之后就不能改,想要对他进行改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
3. java中的字符串:String,StringBuider,StringBuffer.
String是典型的Immutable类,也就是不可变的类型,对于String对象的任何更改都会产生一个新的对象.
StringBuffer为了解决字符串凭借产生太多中间对象的问题而提供的一个类,吧字符串添加到已有序列的末尾或者指定位置.StringBuffer是一个线程安全的可修改字符串序列,实现线程安全的方法就是在方法上添加synchronized修饰符,
StringBuilder大部分和Stringbuffer相同,但是是线程不安全的,所以比较快.
3.1 关于字符串的设计与实现考量:
StringBuffer和StringBuilder底层都是char[]数组(1.9之后是byte[]).
jdk1.8之后字符串拼接底层使用的是StringBuilder
3.2 String缓存:
String的intern()方法,会提示jvm将需要的字符串进行缓存起来存放在堆内存中.
4. SpringMvc执行流程。
答:
5. HashMap创建后需要设置长度吗?
需要,底层是数组,默认长度16,如果不设置长度,多次插入数据会多次创建新的数组对象。
6. volatile是线程安全的吗?
不是,多线程共享,但是不能保证原子性。
7. SpringMvc为什么被设计成为单例模式?如何设置为多例?
因为SpringMvc是基于方法进行访问的,如果一次访问就创建一个实例,对程序压力很大,如果想要改为多例模式,将类上添加scope(value=singleton)。
8. SpringMvc调用同类的方法,为什么事务会不起作用?
使用声明式事务,会在调用之前和结束之后环绕式增强,但是目标对象内部调用自己是无法进行事务增强的,所以事务会失效。
9. SpringMvc中的AOP的原理:
静态代理和动态代理,
静态代理:代表为Aspect,就是在编译期间生成AOP静态代理类。
动态代理 : 分为jdk自带的动态代理技术,和Cglib。
JDK动态代理:使用反射接收被代理的类,要求被代理的类必须实现一个接口,主要的接口时invokcation和Proxy代理类。
Cglib:通过创建被代理类子类的方法,进行动态代理。如果被代理类为final修饰的则无法使用Cglib方法进行动态代理。
当目标对象没有实现接口,则会使用Cglib实现动态代理。
10. Spring中IOC的原理:
Spring启动时读取配置文件,在容器中生成一份bean配置注册表,然后通过反射创建这些bean对象的实例,分配依赖关系,为上层应用提供准备就绪的应用环境。
11. Spring如何读取Web.xml:
通过Servlet读取web.xml。
12. 分布式唯一ID如何保证:
1. 使用数据库自增主键。缺点:分表的时候会出现问题。
2. 使用UUID。缺点:没有业务。
3. 使用Redis生成唯一主键ID,redis 是单线程的利用redis的原子性,可以保证主键id不重复。缺点:配置复杂。
13. Session分布式管理方案:
1. Session复制:在支持Session复制的web服务器上,通过修改servel.xml中配置。缺点:使用与集群服务器数量十台一下,而且需要web服务器能够支持。
2. Session粘滞:将用户每次请求都特定的发布到某一个web服务器上,只要这个web服务器存储session信息就可以。缺点:一但这个web服务器宕机或者重启,session数据就会丢失。
3. Session集中管理:将session存储在redis中,集中管理所有的session,redis中存储sessionID。缺点;redis配置麻烦。
4. 基于Cookie管理:每次请求将session数据放到Cookie中传递给服务端。缺点:不安全。
14. 分布式锁实现的集中方案:
在不同进程需要访问共享资源的时候,分布式锁是如何办证进程安全的有效方式。
1. 基于数据库的分布式的实现:创建一张锁表,用于存储每个方法的锁,当有一个方法被使用,则创建锁,其他线程进行等待,方法结束则删除数据。
2. 放入Redis中实现
15. JSP和Servlet区别:
JSP会被jsp引擎转化成为Servlet,然后在由jsp引擎调用编译之后会成为java类。
Servlet中不存在内置对象,而JSP存在内置对象,但是都是通过HttpServletRequest,HttpServletResponse,和httpServlet获取的。
JSP是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。
而Servlet是一个完整的类,这个类的Service方法用于生成对客户端的响应。
16. 百万级数据库的优化:
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,所以不要留null。
3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,可以选择使用union all字段连接两段查询语句。
5.in 和 not in 也要慎用,否则会导致全表扫描,如果是连续的数值,可以考虑使用between,
6.使用like也会导致全表扫描。
7.避免在条件中执行表达式和函数操作,这样将导致放弃索引,进行全表扫描。
17. jvm调优参数:
1.-server:如果设置一定要作为第一个参数,此参数设置jvm的模式。64位不需要设置,默认就是server模式。(server模式启动慢,运行快。)
2.-Xms:表示java初始化堆的大小,-Xms与-Xmx设置成为一样的值,可以避免JVM反复重新申请内存,默认额值为物理内存的1/64,默认空余堆内存小于40%时,JVM就会增大堆到-Xmx的最大限制。
3.-Xmx:表示java堆最大值,默认为物理内存的1/4.
4.-Xss:表示每个java线程堆栈大小,在相同的物理内存下,减小这个值能生成更多的线程,设置不应该超过1M,不然容易出现oom异常。
5.
-XX:NewSize:新生代大小
-XX:MaxNewSize:设置最大新生代内存大小。
.-XX:PermSize:设置持久代内存大小
.-XX:MaxPermSize:设置持久代内存最大大小。
.-XX:+AffressiveOpts:jdk版本升级后会使用最新加入的优化技术。
其他的参数,请自行百度,百度上有很详细的解释。
18. 什么是CAS算法:
CAS是方法 compareAndSet简称,通过就得旧的预期值和新的预期值和内存值三个参数,通过比对旧的预期值与内存值是否相等来判断是否更新成功.相当于乐观锁.源码中使用了非java语言的实现方法.
19. 关于Integer
Integer是int基本类型的包装类,jdk1.5中引入自动拆箱和装箱,拆箱调用intValue()方法,装箱调用valueOf()方法,Integer默认缓存 -128 --- 127 范围的整数,通过更改jvm参数 -XX:AutoBoxCacheMax=N 来更改这个范围.
20. Java集合
在Java中集合的父类为Collection,在他之下有三个接口了它 .
有序,可重复的List
无序,不可重复的Set
一种底层为队列一样先进先出的线性结构的Queue
List:
List在java中有三种重要的实现类.
1. Vector 线程安全,底层为数组,扩容方式为一倍扩容的集合.缺点:效率低 ,采用的是数组随意查询快,插入数据慢.
2. ArrayList 线程不安全,效率高,底层为数组,扩容方式为50%扩容的集合,缺点: 线程不安全,与vector相同也是查询快 插入数据与删除数据慢.
3LinkedList线程不安全,同时实现List和Deque(这个接口实现了Queue接口)两个接口,底层是链表的实现方式,不需要动态扩容,缺点: 链表结构查询慢,插入数据和删除数据快.
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
21. Java线程执行start命令之后就会立刻执行吗?
不会,Java线程执行start命令之后会等待cpu的指令去执行Java线程
22. Java线程的集中状态
1. NEW: 新建状态,线程尚未调用start方法.
2. RUNNABLE:就绪状态.等待cpu调度命令的线程状态,该状态只能意外终止和进入下个状态.
3. RUNNING: 执行状态,线程听从cpu凋零开始执行,可能会执行sleep,wait命令,或者因为阻塞等原因进入BLOCKED状态,或者因为Thread.yield()方法,放弃执行权进入RUNNABLE状态.
4.BLOCKED:锁状态,死锁,或者上条说道sleep等命令进入的BLOCKED状态. 该状态只能意外终结或者进入到RUNNABLE状态中. 通过new Thread().notify()方法.
5TERMINATED:终止状态,线程结束或者异常停止则进入这个状态.
未完待续....