Java常见面试题目考点(二)
1、什么是锁?锁的作用是什么?
锁就是对象.锁的作用是保证线程同步,解决线程安全问题。 持有锁的线程可以在同步中执行,没有锁的线程即使获得cpu执行权,也进不去。
1.1、什么情况下导致线程死锁,遇到线程死锁该怎么解决?
指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。 产生条件: ①互斥条件:线程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个线程所占有。 ②不剥夺条件:线程所获得的资源在未使用完毕之前,不能被其他线程夺走,只能由该线程主动释放 ③请求和保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他线程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。 循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被链中下一个线程所请求。 1.1、如何避免死锁 加锁顺序(线程按照一定的顺序加锁); 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁);
2、说说你对Java中反射的理解
Java反射机制是运行状态中,对于任意一个类,能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法,这种动态获取的信息以及动态调用对象方法的功能称为反射。 反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性. 缺点是对性能有影响, 使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它 满足我们的要求。这类操作总是慢于只直接执行相同的操作。 获取字节码有三种方法: 1. 根据类名:类名.class ,2. 根据对象:对象.getClass() , 3. 根据全限定类名:Class.forName(全限定类名)
2.1、 JVM内存区域划分? (1)类加载器子系统 ①加载:启动类加载, 负责从启动类路径中加载类; 扩展类加载: 负责加载ext 目录(jre\lib)内的类; 应用程序类加载器: 负责加载应用程序级别类路径 ②链接: 校验, 校验生成的字节码是否正确, 准备, 分配内存并初始化默认值给所有的静态变量, 解析,所有符号内存引用被方法区(Method Area)的原始引用所替代 ③初始化:静态代码块被执行 (2)运行时数据区 ①本地方法栈: 执行虚拟机所使用到的本地方法服务 ②java堆: 存放对象实例和数组的区域 ③方法区: 存储已被虚拟机加载的类信息、常量、静态变量等区域 (3)执行引擎 ①编译器, 利用解释器转换字节码 ②垃圾回收机制: VM的垃圾回收只收集哪些由new关键字创建的对象。所以,如果不是用new创建的对象,你可以使用finalize函数来执行清理。
2.2、垃圾回收机制? ①标记/清除算法: 内存中的对象构成一棵树,当有效的内存被耗尽的时候,程序就会停止,做两件事,第一:标记,标记从树根可达的对象(途中水红色),第二:清除(清楚不可达的对象) 缺点:递归效率低性能低;释放空间不连续容易导致内存碎片;会停止整个程序运行; ②复制算法: 把内存分成两块区域:空闲区域和活动区域,第一还是标记(标记谁是可达的对象),标记之后把可达的对象复制到空闲区,将空闲区变成活动区,同时把以前活动区对象1,4清除掉,变成空闲区。 缺点:速度快但是耗费空间 ③标记整理算法: 标记谁是活跃对象,整理,会把内存对象整理成一课树一个连续的空间。
2.3、对象的创建过程?
3、动静态代理的区别,什么场景使用?
静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。 静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道. JDK动态代理是实现JDK里的 InvocationHandler接口的 invoke方法,但注意的是代理的是接口,也就是你的业务类必须要实现接口,通过Proxy里的newProxyInstance得到代理对象。 还有一种动态代理 CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的。 4、 JDK1.8 十大新特性详解
① 允许给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫做扩展方法. ② Lambda 表达式: Collections.sort(names, (a, b) -> b.compareTo(a)); ③ 函数式接口: 指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法 ④方法与构造函数引用: 允许你使用 :: 关键字来传递方法或者构造函数引用 ⑤Lambda 作用域: 可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。 ⑥访问局部变量, 访问对象字段与静态变量 ⑦访问接口的默认方法: 如Stream 接口表示能应用在一组元素上一次执行的操作序列. ⑧Date API: Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。 ⑨Annotation 注解: 支持多重注解, 只需要给该注解标注一下@Repeatable即可。 ⑩Java 8引入了一个新的Optional类: 这是一个可以为 null 的容器对象。如果值存在则 isPresent() 方法会返回 true ,调用 get() 方法会返回该对象。
5、Java中的设计模式和回收机制?
①创建型模式:工厂方法模式,抽象工厂模式,单例模式,建造者模式 ②结构型模式:适配器模式,代理模式,装饰者模式 ③行为型模式:策略模式,观察者模式 工厂方法模式分为三种:普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。 多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。 静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。 抽象工厂模式: 工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,此时就需要用到工厂模式,创建多个工厂类, ,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。 建造者模式: 而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的。 适配器模式: 适配器模式将某个类的接口转换成客户端期望的另一个接口表示, 主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。 装饰者模式: 装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。
6、Java的基本数据类型
8种基本数据类型: byte 1 char 2 short 2 int 4 float 4 double 8 long 8 boolean 1, String是引用类型,底层用char数组实现的。
7、jvm为什么设计成一个进程?
JVM是一份本地化的程序,本质上是可执行的文件,是静态的概念。程序运行起来成为进程,是动态的概念。实际上,多个进程可以并发执行同一个程序,java程序是跑在JVM上的,严格来讲,是跑在JVM实例上的,一个JVM实例其实就是JVM跑起来的进程,二者合起来称之为一个JAVA进程。
8、 既然有GC机制,为什么还会有内存泄露的情况?
理论上Java 因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是 Java 被广泛使用于服务器端编程的一个重要原因)。然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被 GC 回收,因此也会导致内存泄露的发生。 例如 hibernate 的 Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。
9、说下原生jdbc操作数据库流程?
第一步:Class.forName()加载数据库连接驱动; 第二步:DriverManager.getConnection()获取数据连接对象; 第三步:根据SQL获取sql会话对象,有2种方式 Statement、PreparedStatement ; 第四步:执行SQL处理结果集,执行SQL前如果有参数值就设置参数值setXXX(); 第五步:关闭结果集、关闭会话、关闭连接
10、GET和POST的区别?
①GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连. ②GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据。 ③POST的安全性要比GET的安全性高。通过GET提交数据,用户名和密码将明文出现在 URL 上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了。
|