1.String、StringBuffer 和 StringBuilder 的区别:
String:不可变字符串; String 字符串的 + 法实际是生成了新的 String 对象,如果频繁滴有 + 操作,那么效率可能会很差;
StringBuffer:线程安全的可变字符串; 使用 append 来进行连接 + 操作, 如果频繁有字符串 + 操作,应该采用;
StringBuilder:非线程安全的可变字符串;如果频繁有字符串 +,那么可以采用,效率比 StringBuffer 会高那么一点,但注意是非线程安全的;
String.intern()方法: 将字符串对应值放到常量区。
2. 将构造函数声明为 private 有哪些用途 ?
类外不能直接构造对象(实例化这个类),如果要获取对象那么只有通过 static 的 public 方法,单例模式和工厂模式常如此用;
该类不能继承。
3. try-catch-finally 的 try 块中如果有 return 语句, finally 块是否还会执行?
会。 finally 语句会在 return 之前执行,但是会在 return expression 的 expression 求值之后。
随之一个问题:try 块中 return 1 而 finally 块中 return 2 ,那么函数是返回 1 还是 2 呢? —— 答案是 2 。这也说明,如果 try/catch 块中 throw Exception ,而 finally 中 return 值,那么异常也不会真 throw 到外层。
4. 在哪些情况下 try-catch-finally 结构中的 finally 语句块不会执行?
如果虚拟机在 try/catch 语句块执行期间退出;除了 power off 或是 reset 这些外部不可抗拒的因素外,System.exit(1) 也会造成 JVM 异常退出,这时候 finally 块可能还来不及执行;
如果执行 try/catch 语句块的线程被杀死终止了。
5. final、finally 和 finalize 的使用场景 ?
final 用在不同的地方含义也不同:
修饰变量,表明变量初始化之后不可修改,也就是不能重新赋值;如果 final 来修饰对象,只表明不能重新赋值,但可以修改对象的值;
修饰方法,表明方法不能重写;
修饰类,表明类不能继承;final 和 abstract 不能同时修饰一个类,因为前者说明不能继承,后者则必须继承才能实例化;
finally 是 try-catch-finally 块的一部分, 可选。 try/catch 块执行之后一定会执行的一部分,一般用于资源回收或是垃圾清理。 (当然在某些极端情况下, finally 不会执行。)
finalize() 方法: 当 gc 要回收一个对象之前会执行 finalize() 方法。
6. Java 泛型 和 c++ 泛型的区别。
最核心区别: c++ 中泛型中的类型是泛型类的一部分, java 中不是。
7. java 的 major.minor 版本
运行java程序有时候会遇到的一个问题:Exception in thread “main” java.lang.UnsupportedClassVersionError: org/apache/catalina/util/ServerInfo : Unsupported major.minor version 51.0 ,这说明当前的 JRE 版本和 class 要求的版本不一致, 51.0 表明需要 JRE7。
Java major.minor 会存在字节码中,具体 major 版本对应的 JDK:
J2SE 8 = 52
J2SE 7 = 51
J2SE 6.0 = 50
J2SE 5.0 = 49
JDK 1.4 = 48
JDK 1.3 = 47
JDK 1.2 = 46
JDK 1.1 = 45
8. JRE 的 rt.jar 中包的结构,或是有哪些包?
rt.jar 有 java., javax., com., org., sun., sunw. 六个包,其中前四个为 public 包,api 一般保持兼容; 后两个为非 public 包,不同系统上的实现可能不同,也不保证兼容性。
9. switch() 可以跟的类型有哪些?
jdk7 之前只能支持 char, byte, short, int 四种整型, jdk7 开始支持 String 类型。long 是不支持的呀!
10. == 和 equals() 的区别?
== 用来比较相等,可以用于基本类型和引用类型;equals() 是对象(引用)来比较相等。 == 用于对象的时候,比较的是“是否引用的同一个对象”,而非“内容是否相等”; equals() 往往是比较“内容是否相等”。需要注意的是 String 和 Long(包括 Integer 等):
String s1=”hello”, s2=”hello”, s3=new String(“hello”), s4=new String(“hello”) : s1 == s2 true,其他 == 比较都是 false 。 任意一个 equals() 比较都是 true !
Integer i = 10; Long l = 10L; i == l 和 i.equls(l) 都是 false,后者是因为 Integer/Long.equals() 首先比较类型是否相同其次比较 value 是否 == !
11. Object 类以及常用方法?
Object 是 Java 中所有类的祖先类:一个类要么直接继承要么间接继承自 Object。一个类如果没有显式地继承一个类,那么默认 extends Object 。
Object 的几个方法: toString(),equals(),hashCode(),以及 getClass(),clone() 和finalize()。另外几个用于线程类: wait() 、notify() 和 notifyAll() 。
toString() : 对象字符串化的格式, 除了直接调用之外,在字符串拼接 + ,或是 print 的时候会调用之;
equals(): 定制对象相等比较的逻辑,集合类的 contains() 方法会调用之;
hashCode() : 哈希值,一个 int 值; (同一个进程中)同一个对象的 hashCode() 相等, equals() 相等的对象的 hashCode() 也应该相等,除此之外可以相等也可以不相等;
getClass() : 获取类对应的 Class<?> 类对象;
clone() : 拷贝逻辑;
finalize() : gc 之前的处理逻辑;
12. 换行符是神马?
跟换行符有关的两个字符\r (CR: carriage return)
和 \n (LF: line feed)
。 windows 下换行符是 \r\n
, *unix
是 \n
, mac 下最初是 \r (直到 Mac OS Version 9)后来是 \n (Mac OS X)。╮(╯▽╰)╭ 有没有一种错乱的感觉! 所以 System.out.println() 和 System.out.print('\n')
是有差异的!System.out.println()
和 System.out.printf("%n")
是一致的。
获取换行符: System.lineSeparator(); 或是 System.getProperty(“line.separator”);
13. java 的 system properties 有哪些?
具体有哪些可以通过 System.getProperties() 查看。有一些是系统定义的,有一些是应用程序定义的,不过我们主要系统定义的一部分。
Java相关:”java.home”, “java.library.path”, “java.class.path”, “java.ext.dirs”,”java.version”, “java.runtime.version” 分别是: JRE目录、native库目录、load库目录、扩展库目录,java版本,jre版本;
分隔符相关: “file.separator”, “path.separator”, “line.separator” 分别是文件分隔符、路径分隔符和换行分隔符;
用户相关:”user.home”, “user.name”, “user.dir” 分别是用户主目录、用户名以及用户当前目录;
os相关:”os.name”, “os.version”, “os.arch” 分别是操作系统名称、版本、平台;
14. 三元表达式
三元表达式 a ? b : c 在某些场景下是 if…else… 很好的替代品。语义就是如果 a 为 true 则 b 的值作为表达式的值, 否则 c 的值作为表达式的值。很好理解。不过需要注意的是 boolen f = true; f ? 10 : 12.5 的结果的值是 10.0 而非 10,原因是表达式 b 和 c 部分的类型需要保持一致,如果不一致会进行默认的类型转换,这里 int 的 10 会转换为 double 的 10.0 。
15. 求余运算 % 和整数除法 /
求余运算通常能得到预期的结果,譬如 13 % 3 == 1 。但是 -13 % 3 == ? 13 % -3 == ? -13 % -3 == ?
上面答案分别是:-1
、1
和 -1
。记忆方式也挺简单,就是余数的符号和被除数的符号一致。
对应的需要注意:13/3 == 4
, -13/3 == -4
, 13%-3 == -4
, -13/-4 == 3
。总之符合: a = (a/b)*b + (a%b)
。
16. volatile 关键字
volatile
修饰变量 v 的话,表明变量 v 的值对外具有一致性。也就是说即使在多线程环境下,如果 v 的值修改了,那么去读 v 的值能取到新的 v 值,否则不一定。
v 可以用来修饰基本类型的变量,譬如 int 型, 或是对象。对于后者只是保证引用的对外一致性,而引用的对象的修改不在“一致”范围内。
so,volatile
具有部分线程同步功能,特别是“一写多读”的情形。
17. synchronized 关键字
synchronized
可以用来修饰普通方法、类方法或是对象,来控制对方法或是对象的互斥访问。
18. SimpleDateFormat
java doc
上有云“Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.”。
所以,SimpleDateFormat
作为 static
变量共享的时候需要显式同步,譬如用 synchronized
。另外一种处理是借助 ThreadLocal
,这样同一个线程内是安全的,又不需要每一次进行同步。如果将 SimpleDateFormat
作为 local
变量,当然也是线程安全的,只不过每次使用都需要进行重新构造。
转载自:文琼