java面试必备

arraylist和linklist的区别:
arraylist是基于动态数组,方便查询,可以按下标查。正常情况下对增删元素的性能不如linklist
linklist是基于链表,方便增删,但由于在插入大量数据的时候会创建很多个节点,如果arraylist也是用了尾插法去增加元素的话,其实arraylist的效率还是可以的。
hashcode和equal:
hashcode返回一个hash值,equal则是比较值或者对象是不是同一个,例子:hashset:set不允许元素重复无序,所以需要先用hashcode的方法返回一个hash值,如果值相同会再调用一个equal的方法比较是否为同一个对象。
hashmap和hashtable的区别:
hashmap是线程不安全的(基于数组加链表)。hashtable是线程安全的(加了一个syc),hashmap允许key和value的值为null,hashtable不允许的。现在都不用hashmap,而是用concrurrenthashmap(线程安全的)
orm框架:面向对象的数据模型和关系型数据的装换
spring7大模块:1.spring core(spring 底层核心模块,实现IOC模式,有一个核心类,BeanFactory,负责Javabean的配置和管理)。2.spring aop(能够使任何对象aop化)。3.spring orm(提供了对大部分orm框架的支持)。4.spring dao(对业务逻辑和数据库的代码进行分离,降低两者的耦合)。5.spring web(建立在spring context上,对现有的web框架进行了集成)。6.spring context(继承beanfactory,增加了事件处理,国际化,数据验证等功能)。7.spring webmvc (能够适应多种视图,实现控制逻辑代码和业务逻辑代码清晰分离)。
ioc创建对象的三种方式:(构造器注入)第一种可以通过下标。第二种可以通过参数类型。第三种可以通过变量参数名。(无参构造方法也行)。
spring加载配置文件的时候就已经实例好对象。
别名alias或者<bean id="",class="",name="">
import 可以导入其他配置文件
bean注入用ref(set注入)
p命名空间注入(set)和c命名空间注入(构造器),需要导入xml约束。
autowire自动装配:byname,只要bean的id唯一,然后这个bean需要和自动注入的set的值一样。bytype,只要bean的class唯一,然后这个bean需要和自动注入的set的类型一样。
@Autowire(false)表示此对象可以为null,如果是在比较复杂的配置里,可以使用@Qualifile(value="")配合autowife指定一个唯一的bean对象注入。@Resource(java源注解)同autowire一样可以实现自动装配。区别:autowire是通过先bytype,而resource则是通过byname,然后再去bytype。
bean有五种作用域:singleton(默认),prototype,request,session,globalsession.
@Component注解相当于<bean id="",class="">帮我们注册好了bean,@value(""),@scope(“作用域”)。
静态代理模式(一个角色会产生一个代理,真实角色只需要关心必要操作,公共操作可以交给代理对象)
动态代理模式:如下例子:

public class InvocationHander implements InvocationHandler {

    //被代理的接口
    private Object host;

    public void setHost(Object host) {
        this.host = host;
    }
//生成一个代理类
    public Object getProcy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),host.getClass().getInterfaces(),this);
    }
    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=method.invoke(host,args);
        return result;

    }
}

测试:

 public static void main(String[] args) {
        host host=new host();
//        proxy proxy=new proxy(host);
//        proxy.rent();
    InvocationHander invocationHander=new InvocationHander();
    invocationHander.setHost(host);
    //动态生成代理类
        rent proxy=(rent)invocationHander.getProcy();
        proxy.rent();
    }

我们梳理一下,首先我们有角色房东,租客,中介。
我们新建一个房东的需求接口,然后房东类实现需求接口,租客有租房需求,但是不能直接找房东,而是通过找中介,而中介就相当于代理,帮房东处理一些不必要的操作,如签合同,看房等,此时可以用静态代理模式,写一个中介代理类,在类中写一个有参的构造方法,参数为一个对象(一般为真实角色的对象),然后在测试类中实例化一个代理类和真实角色类,最后用代理对象调用真实角色方法。而动态方法没有说写一个固定角色的代理类,而是动态代理,此时类中的对象并不是固定的,而是Object类型,即任何对象,然后就是一个固定的写法:1,实现InvocationHandler接口,然后重写invoke(Object proxy, Method method, Object[] args),返回一个对象,一般在此方法添加一些公共操作,然后自定义一个生成代理类的方法。
然后我们就可以在测试类根据不同的角色添加不同的代理(动态代理代理的是接口)。
aop也是基于动态代理实现的。
aop的实现方式:
1.用原生的spring api接口,第一步,找切入点(要切入到哪个类中,execution(*包名*.*(..)),第二步执行环绕增加。
2.自定义类实现aop,第一步,找切面(一般是我们的新添加的类,先注册为bean),第二步,找切入点,第三步,通知.
3.使用注解实现aop,第一步,在配置文件中开启aop注解,第二步,注册切面的bean,第三步,在切面的那个类加上@Aspect(表示此类为一个切面),第四步, @Befoce(execution 切入点),@After,@Around()。
ACID原则:原子性(确保一组业务要么都成功,要么都失败),一致性(事务一旦被提交就要保证资源和状态一致),隔离性(多个业务操作同一个资源,互相隔离,保证数据完整),持久性(事务一旦被提交,无论发生什么事情,结果都不会改变,被持久化的写入到我们的存储器中)。
spring声明式事务:
源代码->编译器(字节码,即class文件)->jvm->jvm解释器->机器可以识别的二进制机器码。优点:跨平台,效率高,无需重新编译。
三个类加载器:bootstraploader,extclassloader,appclassloader.
双亲委派模型:向上是查找缓存,向下是查找加载路径。
优点:避免被自定义的类替换java的一些核心类,主要为了安全性。
Throwable是异常的最顶类,然后分为Excetion,error(程序无法处理的错误,会导致程序被迫停止,例如oom(内存异常)),Excetion又分为RuntimeExcetion(运行时异常)和CheckedExcetion(编译时异常).
gc如何判断对象是否可以回收:1.引用计数法(不被java所采用),2.可达性分析法(从gcroot 开始向下搜索,搜索所走过的路称为引用链,当一个对象到达gcroot时没有如何引用链相连时,那就证明此对象是不可用的,那么虚拟机就会判断为可回收对象。)。gcroot对象有,虚拟机栈中引用的对象,方法区静态引用的对象,方法区中常量引用的对象,本地方法栈中JNL(即本地native方法)引用的对象。
java线程的生命周期:初始状态(线程被创建)->运行状态(把就绪和运行归一,调用start方法)->阻塞状态(等待阻塞(像sleep,join,wait),同步阻塞(运行的线程拿到同步锁),其他阻塞(如发出i/o请求,会把此线程设置为阻塞状态))->等待状态(没有超时时间)->超时等待状态(超时)->终止状态。
sleep和wait的区别:1.sleep是继承自Thread的类的本地方法,wait是继承自object类的本地方法。2.sleep不会释放锁,wait会释放锁。3.sleep不依赖于synchronized,但wait依赖于synchronized.4.sleep不需要被唤醒,wait需要。
yield:线程会直接回到就绪状态。
join:线程进入阻塞状态,例如:B线程执行了A线程中的join方法,那么B线程就会进入阻塞状态,直到A线程结束或者中断。
守护线程:GC垃圾回收器
ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线程访问出现线程不安全的方法,当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题。缺点,处理不当会发生内存泄露。解决方法,每次用ThreadLocal都要调用一下remove方法,将ThreadLocal的变量设置为private和static,保证一直保持强引用。
并发(两个任务交替执行,可以互相干扰),并行(两个任务同时刻,互不干扰),串行(前一个任务没有完成,下一个任务就得等待)。
并发的三大特性:原子性(一个或者多个操作,要么全部执行(执行的过程是不会被打断的)、要么全部不执行。),可见性(一个线程对共享变量的写入时,能对另一个线程可见),有序性(处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。)。
原子性的解决:内置锁(同步关键字):synchronized;显示锁:Lock;自旋锁:CAS;
可见性:在这里插入图片描述
共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入时,能对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在
从上图来看,线程A与线程B之间如要通信的话,必须要经历下面2个步骤:

  1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
  2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。

当然,我们可以用synchronized来保证这个过程。但是Java1.5以后提供了更加轻量的锁volatile

Volatile与Synchronized区别
(1)从而我们可以看出volatile虽然具有可见性但是并不能保证原子性。
(2)性能方面,synchronized关键字是防止多个线程同时执行一段代码,就会影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized。但是要注意volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。
有序性:单线程(重排序),多线程(避免重排序-happen-before原则)。
ACID是通过日志来保证的,A是通过undo log日志,C是通过其他三大特性来保证,I是通过MVCC,D是通过内存+redo log来保证。
MyIsam和InnoDb的区别:MyIsas是不支持事务的,Innodb可以。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值