java中的四种引用:
强引用(Strong Reference):
最常见的普通对象引用,如果有强引用就证明这个对象还活着.这样同样也可以确定 当我们想要垃圾回收装置将无用的对象回收的时候,只要将引用赋值为null就可以了.
软引用(Sort Reference):
被软引用引用的对象,如果当jvm内存不足的时候会清理掉.
SoftReference<String> sr = new SoftReference(new String("hello"));
软引用通常配合引用队列向使用.
弱引用(WeakReference):
弱引用更弱,不能豁免垃圾收集,有就用没有就只好重现实例化.
WeakReference sr = new WeakReference(new String("hello"));
幻想引用(PhantomReference):
不能通过他访问对象,仅仅是能提供确保对象呗finalize以后做某些事的机制.
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);
如何声明对象强可达?
java.lang.ref.Reference类的static void reachabilityFence(Object ref)方法.可以标记对象强可达.
未完待续......
什么叫做Immutable 类?
就是不可变类,如果改变就是创建了一个新对象,String就是这种类.
创建一个Immutable 类,首先类需要被final 修饰,属性不能提供set方法,属性也要私有并且被final修饰,大致规则如下
1)immutable对象的状态在创建之后就不能改,想要对他进行改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
java中的字符串:String,StringBuider,StringBuffer.
String是典型的Immutable类,也就是不可变的类型,对于String对象的任何更改都会产生一个新的对象.
StringBuffer为了解决字符串凭借产生太多中间对象的问题而提供的一个类,吧字符串添加到已有序列的末尾或者指定位置.StringBuffer是一个线程安全的可修改字符串序列,实现线程安全的方法就是在方法上添加synchronized修饰符,
StringBuilder大部分和Stringbuffer相同,但是是线程不安全的,所以比较快.
关于字符串的设计与实现考量:
StringBuffer和StringBuilder底层都是char[]数组(1.9之后是byte[]).
jdk1.8之后字符串拼接底层使用的是StringBuilder
String缓存:
String的intern()方法,会提示jvm将需要的字符串进行缓存起来存放在堆内存中.
SpringMvc执行流程。
答:
HashMap创建后需要设置长度吗?
答:需要,底层是数组,默认长度16,如果不设置长度,多次插入数据会多次创建新的数组对象。
volatile是线程安全的吗?
答:不是,多线程共享,但是不能保证原子性。
SpringMvc为什么被设计成为单例模式?如何设置为多例?
答:因为SpringMvc是基于方法进行访问的,如果一次访问就创建一个实例,对程序压力很大,如果想要改为多例模式,将类上添加scope(value=singleton)。
SpringMvc调用同类的方法,为什么事务会不起作用?
答:使用声明式事务,会在调用之前和结束之后环绕式增强,但是目标对象内部调用自己是无法进行事务增强的,所以事务会失效。
SpringMvc中的AOP的原理:
答:静态代理和动态代理,
静态代理:代表为Aspect,就是在编译期间生成AOP静态代理类。
动态代理 : 分为jdk自带的动态代理技术,和Cglib。
JDK动态代理:使用反射接收被代理的类,要求被代理的类必须实现一个接口,主要的接口时invokcation和Proxy代理类。
Cglib:通过创建被代理类子类的方法,进行动态代理。如果被代理类为final修饰的则无法使用Cglib方法进行动态代理。
当目标对象没有实现接口,则会使用Cglib实现动态代理。
Spring中IOC的原理:
答:Spring启动时读取配置文件,在容器中生成一份bean配置注册表,然后通过反射创建这些bean对象的实例,分配依赖关系,为上层应用提供准备就绪的应用环境。
Spring如何读取Web.xml:
答:通过Servlet读取web.xml。
分布式唯一ID如何保证:
1. 使用数据库自增主键。缺点:分表的时候会出现问题。
2. 使用UUID。缺点:没有业务。
3. 使用Redis生成唯一主键ID,redis 是单线程的利用redis的原子性,可以保证主键id不重复。缺点:配置复杂。
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中传递给服务端。缺点:不安全。
分布式锁实现的集中方案:
在不同进程需要访问共享资源的时候,分布式锁是如何办证进程安全的有效方式。
1. 基于数据库的分布式的实现:创建一张锁表,用于存储每个方法的锁,当有一个方法被使用,则创建锁,其他线程进行等待,方法结束则删除数据。
2. 放入Redis中实现
JSP和Servlet区别:
JSP会被jsp引擎转化成为Servlet,然后在由jsp引擎调用编译之后会成为java类。
Servlet中不存在内置对象,而JSP存在内置对象,但是都是通过HttpServletRequest,HttpServletResponse,和httpServlet获取的。
JSP是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。
而Servlet是一个完整的类,这个类的Service方法用于生成对客户端的响应。
百万级数据库的优化:
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,所以不要留null。
3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,可以选择使用union all字段连接两段查询语句。
5.in 和 not in 也要慎用,否则会导致全表扫描,如果是连续的数值,可以考虑使用between,
6.使用like也会导致全表扫描。
7.避免在条件中执行表达式和函数操作,这样将导致放弃索引,进行全表扫描。
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版本升级后会使用最新加入的优化技术。
其他的参数,请自行百度,百度上有很详细的解释。
未完待续....
网友评论