一次
1.String a="a";String b = new String("a");区别
java虚拟机会将其分配到常量池中;而String str = new String("i")则会被分配到堆内存中。
1.常量池和堆区别
常量池:存放字符串常量和基本类型常量(public static final)。 常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。
堆:一种通用性的内存池(也存在于RAM中),用于存放所以的JAVA对象。
1.值传递,引用传递
值传递:在方法被调用时,实参通过形参把它的内容副本传入方法内部
,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容
引用传递:引用也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响到真实内容
java传递一个对象,然后调用set方法,改变。直接复制不改变。
1. 数据库的三范式是什么?
第一范式:字段不可分;(列都不可以在拆分。)
第二范式:有主键,非主键字段依赖主键;(不能是依赖于主键的一部分。)
第三范式:非主键字段不能相互依赖。(非主键列只依赖于主键,不依赖于其他非主键。)
1.Spring事务七大传播机制和五隔离级别
一、spring支持7种事务传播行为
1、propagation_required(xml文件中为required)
当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将
2、propagation_supports(xml文件中为supports)
当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行。
3、propagation_mandatory(xml文件中为mandatory)
表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常。
4、propagation_nested(xml文件中为nested)
如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation_required的一样。
5、propagation_never(xml文件中为never)
当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常。
6、propagation_requires_new(xml文件中为requires_new)
当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。
7、propagation_not_supported(xml文件中为not_supported)
方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行。
二、spring中的事务隔离级别
1、isolation_default
使用数据库默认的事务隔离级别。
2、isolation_read_uncommitted(读未提交)
允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读。
3、isolation_read_committed(读已提交)
允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生。
4、isolation_repeatable_read(可重复读)
对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生。
5、isolation_serializable(可序列化)
完全服从acid隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。
1.实现接口验证和无需验证执行,
拦截器
// 登录拦截器
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns(
"/shop/**",
"/voucher/**",
"/shop-type/**",
"/upload/**",
"/blog/hot",
"/user/code",
"/user/login"
).order(1);
1.Mybatis的Dao到xml是怎么做的
1.MyBatis会检查配置文件Dao.xml,对文件进行解析,通过mapper标签对dao接口进行一对一的映射。
获取sqlsession对象执行sql,用动态代理获取代理对象
//1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.1 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
1.动态代理(jdk,cglib)
创建目标对象
创建InvocationHandler接口实现类,在invoke方法里增强
使用Proxy.newProxyInstance创建代理类。(反射)
1.cglib动态代理
jdk和cglib区别就是jdk动态代理需要提供接口,cglib不需要。、JDK动态代理,利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理;2CGLIB动态代理,利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1.JVM执行流程
-
执行 javac 命令编译源代码为字节码.class
-
执行 java 命令
-
创建 JVM,调用类加载子系统加载 class,将类的信息存入方法区
-
JVM创建 main 线程,使用的内存区域是 JVM 虚拟机栈,开始执行 main 方法代码
-
如果遇到了未见过的类,会继续触发类加载过程,同样会把类信息存入方法区
-
需要创建对象,会使用堆内存来存储对象
-
不再使用的对象,会由垃圾回收器在内存不足时回收其内存
-
调用方法时,方法内的局部变量、方法参数所使用的是 JVM 虚拟机栈中的栈帧内存
-
调用方法时,先要到方法区获得到该方法的字节码指令,由解释器将字节码指令解释为机器码执行
-
调用方法时,会将要执行的指令行号读到程序计数器,这样当发生了线程切换,恢复时就可以从中断的位置继续
-
对于非 java 实现的方法调用,使用内存称为本地方法栈(见说明)
-
对于热点方法调用,或者频繁的循环代码,由 JIT 即时编译器
-