/images/avatar.png

谈谈对JVM内存分配

JVM的分区可分为三个:堆(heap)、栈(stack)和方法区(method):堆主要用来存放对象的,栈主要是用来执行程序的

堆区

  1. 存储的是对象,并且JVM只有一个堆区,被所有线程共享。
  2. 比如new string等等对象
  3. 由于要在运行时动态分配内存,存取速度较慢
  4. 先进先出

栈区

  1. 每个线程包含自己的一个栈区,栈中只保存基本数据类型的对象和自定义对象的引用记住是引用地址,指向堆中的对象
  2. 栈与栈之间不能直接访问
  3. 存取速度快,但是生命周期是固定的区域。
  4. 先进后出

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义: int a = 3; int b = 3; 编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。

Mybatis与hibernate

总的来说,Hibernate使用的是封装好的,通用的SQL来应付所有场景,而Mybatis是针对响应的场景设计的SQL。Mybatis的SQL会更灵活、可控性更好、更优化

  • Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。
  • Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。
  • Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。
  • hibernate迁移性相对mybatis较好,因为hibernate不是依赖数据库。

对SSM的理解

  • MyBatis:持久层框架,负责数据库访问。
  • Spring MVC:表现层框架,把模型、视图、控制器分离,组合成一个灵活的系统。
  • Spring: 整合项目的所有框架,管理各种Java Bean(mapper、service、controller),事务控制。

Spring中的IOC(控制反转)、DI(依赖注入)、AOP(切面)

  1. IOC(Spring核心)可以认为是一个生产和管理bean的容器(可以管理bean的生命周期);在原来需要new对象时,现在不需要了。
  2. DI注入方式有三种
  • set注入(根据属性注入)
  • 构造方法注入
  • 根据接口注入
  1. IOC与DI可以理解为:

控制反转是动态的向某个对象提供他所需要的对象,这一点是通过DI依赖注入实现的。

  1. AOP面向切面:是一种编程思想,将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,注入到目标对象中。
  2. AOP是通过代理实现的:可以是JDK动态代理,也可以是cglib代理,前者基于接口,后者基于子类。

final、static、volatile、synchronized常见面试问题

记住两点 final不可改变 static 静态全局.

final、finally、finalize的区别

  1. final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
  2. finally 是异常处理语句结构的一部分,表示总是执行.
  3. finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. JVM不保证此方法总被调用.

Static关键字

static 关键字可以用来修饰类的变量,方法和 内部类。static 是静态的意思,也就它定义的东西是全局的意思,属于全局与类相关,不与具体实例相关。就是说它调用的时候,只是ClassName.method(),而不是 new ClassName().method()。new ClassName()不就是一个对象了吗?static 的变量和方法不可以这样调用的。它不与具体的实例有关。

  • JAVA类首次装入时,会对静态成员变量或方法进行一次初始化分配内存空间,但方法不被调用是不会执行的。所以静态内部类在调用时才加载分配空间。仔细一想:静态内部类其实和外部类的静态变量,静态方法一样,只要被调用了都会让外部类的被加载。

String、StringBuffer、StringBuilder的区别

String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象

简要的说

  1. String 字符串常量
  2. StringBuffer 字符串变量(线程安全)
  3. StringBuilder 字符串变量(非线程安全)
  4. String产生新的对象来操作
  5. Stringbuffer类型对自身操作

论效率来说

StringBuilder -> StringBuffer -> String

区别

在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,性能可想而知。