1.java基本数据类型所占字节数
整形:byte 1 short 2 int 4 long 4
浮点型: float 4 double 8
布尔 :boolean JVM规范中Boolean被当作int处理 4
字符型:char 字符型
1.1String 和 char
- 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的 0 个或若干个字符
- 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)
- 占内存大小 字符常量只占 2 个字节; 字符串常量占若干个字节
2.String和StringBuilder、StringBuffer的区别?
String是不可更改的数据类型
StringBuider和StringBuffer是字符串对象使用前需要声明。例:StringBuffer sbr = new StringBuffer();
不同的是,StringBuffer 是线程安全的支持多线程,多线程情况下必须遵守规范使用StringBuffer
而StringBulider适合单线程速度更快。
method:
append delete replace reverse(翻转) insert...
3.反射的用途及实现
Java 反射机制是一个非常强大的功能,在很多的项目比如 Spring,MyBatis 都都可以看到反射的身影。通过反射机制,我们可以在运行期间获取对象的类型信息。利用这一点我们可以实现工厂模式和代理模式等设计模式,同时也可以解决 Java 泛型擦除等令人苦恼的问题。
获取一个对象对应的反射类,在 Java 中有下列方法可以获取一个对象的反射类
- new 一个对象,然后对象.getClass()方法
- 通过 Class.forName() 方法
- 使用 类.class
4.BigDecimal概述
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。
BigDecimal所创建的是对象,故我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
4.1、常用构造函数
-
BigDecimal(int)
创建一个具有参数所指定整数值的对象
-
BigDecimal(double)
创建一个具有参数所指定双精度值的对象
-
BigDecimal(long)
创建一个具有参数所指定长整数值的对象
-
BigDecimal(String)
创建一个具有参数所指定以字符串表示的数值的对象
4.2、常用方法
-
add(BigDecimal)
BigDecimal对象中的值相加,返回BigDecimal对象
-
subtract(BigDecimal)
BigDecimal对象中的值相减,返回BigDecimal对象
-
multiply(BigDecimal)
BigDecimal对象中的值相乘,返回BigDecimal对象
-
divide(BigDecimal)
BigDecimal对象中的值相除,返回BigDecimal对象
-
toString()
将BigDecimal对象中的值转换成字符串
-
doubleValue()
将BigDecimal对象中的值转换成双精度数
-
floatValue()
将BigDecimal对象中的值转换成单精度数
-
longValue()
将BigDecimal对象中的值转换成长整数
-
intValue()
将BigDecimal对象中的值转换成整数
5.把一个逗号隔开的字符串变成一个集合的,类似于("1,2,3")这种
String str = "1,2,3,4";
List<String> result = Arrays.alist(str.split(","));
6.String s = new String("abc")和String s = "abc"的区别
6.1String s = new String("abc")的创建过程
- 系统先在字符串常量池里面寻找是否有一个"abc"的字符串,
- 如果有的话,则在堆中复制一个该字符串,并且将堆中的引用指向s,这个时候系统只创建了一个对象,即堆中的对象;
- 如果没有的话,则会先在字符串常量池中先创建一个字符串为"abc"的常量,然后再复制到堆里面,最后将堆所在的地址指向s,这个时候创建了两个对象;
6.2String s = "abc"的创建过程
- 系统先在字符串中寻找是否存在"abc"的常量
- 如果存在,则直接将该"abc"在常量池中的地址指向s,这个时候,系统没有创建新对象。
- 如果不存在,则在常量池中新建一个"abc"并放入常量池里面,然后再返回该地址,这个时候,系统创建了一个对象。
7.Java中的SPI
SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。
系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦。
SPI与API区别:
- API是调用并用于实现目标的类、接口、方法等的描述;
- SPI是扩展和实现以实现目标的类、接口、方法等的描述;
换句话说,API 为操作提供特定的类、方法,SPI 通过操作来符合特定的类、方法。
8.局部变量和全局变量
- 成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;但是,成员变量和局部变量都能被 final 所修饰。
- 从变量在内存中的存储方式来看:如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用static修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存
- 从变量在内存中的生存时间上看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
- 成员变量如果没有被赋初值:则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。
9.==和equals的区别
==号在比对普通数据类型时比对的是内容,比对对象时的是地址,equals未被重写时作用和==相同,在被重写时比对的是内容,
10.java集合详解
集合大类分为collection 和 map集合
collection集合的子类为set集合和list集合
map集合子类分为hashmap,linstedstack
11.不稳定的排序算法
希尔,堆,快速
12.java多线程
volatile保证线程的可见性和有序性,synchronized保证线程的可见性和原子性
13.java类加载机制
写好的源代码,需要编译后加载到虚拟机才能运行。java 源文件编译成 class 文件后,jvm 通过类加载器把 class 文件加载到虚拟机,然后经过类连接(类连接又包括验证、准备、解析三个阶段),最后经过初始化,字节码就可以被解释执行了。
14.java内存
java8 JVM堆内存(heap) 新生代 老年代 永久代垃圾回收详解_老年代的内存会消失吗-CSDN博客
15.Java锁
16.垃圾处理器
java8 JVM堆内存(heap) 新生代 老年代 永久代垃圾回收详解_老年代的内存会消失吗-CSDN博客
垃圾回收是指自动释放不再使用的内存空间的过程。Java中的垃圾回收器有串行垃圾回收器、并行垃圾回收器和CMS垃圾回收器等。
17.内存泄露和溢出
-
Java中的内存泄漏是什么,如何避免? 答:内存泄漏是指对象不再被使用,但因为某些原因而没有被垃圾回收器回收,导致占用的内存空间不释放。避免内存泄漏的方法有:使用弱引用或软引用,及时释放资源,避免循环引用等。
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
17.1内存泄漏的分类
以发生的方式来分类,内存泄漏可以分为4类:
1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。
从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到
17.2原因及解决方法:
- 内存溢出原因:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.使用的第三方软件中的BUG;
5.启动参数内存值设定的过小 - 内存溢出的原因及解决方法:
- 修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
- 检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误。
- 对代码进行走查和分析,找出可能发生内存溢出的位置。
- 使用内存查看工具动态查看内存使用情况