1.内存中栈、堆和方法区的用法。
栈:基本数据类型变量、对象的引用、函数调用的现场保存;
堆:new关键字和构造器创建的对象,堆是垃圾回收器管理的主要区域;
方法区:jvm加载的类信息、常量、静态变量、JIT编译器编译后的代码、常量池(常量池是方法区的一部分)
2.重载(Overload)和重写(Override)的区别。
1.方法的重载和重写都是实现多态的方式,重载是编译时的多态,重写是运行时的多态。
2.重载:发生在同一个类中,方法名相同,参数类型不同,参数个数不同,或者两者都不同。(对返回值类型没有要求)
3.重写:发生在子类和父类之间,要求子类被重写的方法要和父类的方法拥有同样的返回值类型。
3.JVM 加载 class 文件的原理机制
1.JVM类的装载是类加载器和他的子类来实现的。
2.当 Java 程序需要使用某个类时,JVM 会确保这个类已经被加载、连接(验证、准备和解析)和初始化。
3.类的加载是指把类的.class 文件中的数据读入到内存中,通常是创建一个字节数组读入.class 文件,然后产生与所加载类对应的 Class 对象
4.当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤
5.最后 JVM 对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。
4.抽象类(abstract class)和接口(interface)有什么异同
1.抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。
2.一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类
3.接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法
4.抽象类中的成员可以是 private、默认、protected、public 的,而接口中的成员全都是 public 的
5.抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量
6.有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法
5.# [为什么说 HashMap 是非线程安全的?
1、HashMap 在插入的时候
现在假如 A 线程和 B 线程同时进行插入操作,然后计算出了相同的哈希值对应了相同的数组位置,因为此时该位置还没数据,然后对同一个数组位置,两个线程会同时得到现在的头结点,然后 A 写入新的头结点之后,B 也写入新的头结点,那B的写入操作就会覆盖 A 的写入操作造成 A 的写入操作丢失。
2、HashMap 在扩容的时候
HashMap 有个扩容的操作,这个操作会新生成一个新的容量的数组,然后对原数组的所有键值对重新进行计算和写入新的数组,之后指向新生成的数组。
那么问题来了,当多个线程同时进来,检测到总数量超过门限值的时候就会同时调用 resize 操作,各自生成新的数组并 rehash 后赋给该 map 底层的数组,结果最终只有最后一个线程生成的新数组被赋给该 map 底层,其他线程的均会丢失。
3、HashMap 在删除数据的时候
删除这一块可能会出现两种线程安全问题,第一种是一个线程判断得到了指定的数组位置i并进入了循环,此时,另一个线程也在同样的位置已经删掉了i位置的那个数据了,然后第一个线程那边就没了。但是删除的话,没了倒问题不大。
再看另一种情况,当多个线程同时操作同一个数组位置的时候,也都会先取得现在状态下该位置存储的头结点,然后各自去进行计算操作,之后再把结果写会到该数组位置去,其实写回的时候可能其他的线程已经就把这个位置给修改过了,就会覆盖其他线程的修改。
其他地方还有很多可能会出现线程安全问题,我就不一一列举了,总之 HashMap 是非线程安全的,有并发问题时,建议使用 ConcrrentHashMap。
6.spring 支持集中 bean scope?
Spring bean 支持 5 种 scope:
Singleton - 每个 Spring IoC 容器仅有一个单实例。
Prototype - 每次请求都会产生一个新的实例。
Request - 每一次 HTTP 请求都会产生一个新的实例,并且该 bean 仅在当前 HTTP 请求内有效。
Session - 每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效。
Global-session - 类似于标准的 HTTP Session 作用域,不过它仅仅在基于portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享。在 globalsession 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围内。如果你在 web 中使用 global session 作用域来标识 bean,那么 web会自动当成 session 类型来使用。
仅当用户使用支持 Web 的 ApplicationContext 时,最后三个才可用。
7.spring bean 容器的生命周期是什么样的?
spring bean 容器的生命周期流程如下:
(1)Spring 容器根据配置中的 bean 定义中实例化 bean。
(2)Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
(3)如果 bean 实现BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用setBeanName()。
(4)如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
(5)如果存在与 bean 关联的任何BeanPostProcessors,则调用preProcessBeforeInitialization() 方法。(6)如果为 bean 指定了 init 方法( <bean> 的 init-method 属性),那么将调
用它。(7)最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。(8)如果 bean 实现DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。(9)如果为bean 指定了 destroy 方法( <bean> 的 destroy-method 属性),那么将
调用它。
8.分布事务
10.怎么处理并发
11.springcloud组件
12.JVM
13.查询数据库时,突然感觉查询很慢
14.如何实现多线程
(1)继承Thread类,并重写Thread类中的run()方法,在Thread类中,提供了一个start()方法用于启动新线程,线程启动后,系统就会自动调用run()方法。
(2)实现Runnable接口创建多线程
15.上述两种实现线程的方法有什么不同。
继承Thread类实现多线程,但是这种方式有一定的局限性。因为在java中只支持单继承,一个类一旦继承了某个父类就无法再继承Thread类,比如学生类Student继承了person类,就无法再继承Thread类创建的线程
16.HashMap和HashTable有什么区别
1.Hashmap是线程不安全的,HashTable是线程安全的,所以,HashMap的效率比HashTable要高。
2.HashMap允许有空的键和值,HashTable不允许。
17.Java反射
反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。
18.反射的实现方式都有什么?
获取Class对象,有4种方法:(1)Class.forName(“类的路径”);(2)类名.class;(3)对象名.getClass();(4)基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。
19.java锁
20.spring注解原理
·1-首先你可以通过键值对的形式给注解属性赋值
· 2-java在编译时会扫描方法或属性上的注解是否可以作用在该方法或属性上面,然后将注解信息写入元素的属性表
· 3-当你进行反射时,会拿出所有生命周期在runtime的注解放到一个map中,并创建一个AnnotationInvocationHandler实例,见这个map传给这个实例。
·4-最后Jdk动态代理生成一个目标注解的代理类,并初始化好处理器
总结:注解是是继承了一个Annotation接口的接口,当你通过反射时,其实就是JDK通过动态代理实现注解的代理类
网友评论