你们搞的这个Java啊,Excited!

本文试题题库来源于网络。由于自身姿势水平较低,答案并不一定完全正确。如有意见或建议请联系[email protected]

Java中能创建volatile数组吗?

可以。不过只是一个指向数组的引用,而不是整个数组。如果改变引用指向的数组,将会收到volatile保护,但是多个线程同时改变数组的元素,volatile就不能起到保护。

volatile能使得一个非原子操作变成原子操作吗?

用volatile修饰 long 和 double 类型的变量,可使其变成原子操作。

volatile修饰符实践

原子操作。

内存屏障。当写一个volatile变量的时候,JMM会插入一个写屏障,读之前会插入读屏障。在写volatile域时,能保证任何线程都能看到写的值。在写之前,也能保证任何数值的更新对所有线程可见,因为内存屏障会将其他所有写的值更新到缓存。

volatile类型变量提供什么保证

顺序与可见性,禁止指令重排序,提供 happen-before 保证,确保一个线程的修改对其他线程是可见的。还可以提供原子性

10个线程和2个线程的同步代码,哪个更容易

从代码角度,两者时间复杂度是相同的。同步策略上则不一样,同步策略选择依赖于线程的数量,越多的线程意味着更大的竞争,需要利用同步技术,如锁分离。更复杂

如何调用wait()方法,是使用 if 块还是循环

wait方法应该在循环体中使用,因为当线程获得CPU开始执行的时候,其他条件可能还没有满足。在处理前应该循环检测条件是否满足会更好。

synchronized(obj){

while(condition does not hold){

obj.wait();

}

}

參见Effictive Java

什么是多线程下的伪共享(false sharing)

不同处理器上的线程对于变量的修改依赖于相同的缓存行


什么是Busy spin?为什么要用

自旋锁?不释放CPU资源的情况下等待事件。

如何获取一份线程dump文件

Linux可使用 kill -3 PID(Java进程ID)来获取Java应用的dump文件。Windows下可以按下 Ctrl + break. JVM会将dump文件打印到标准输出或者错误文件中。

Swing是否为线程安全?

不是。原因不知道,不了解Swing。

什么是线程局部变量

ThreadLocal方法:void set(T value)、T get()、T initialValue()

ThreadLocal.每个线程Thread内部有一个Thread.ThreadLocalMap类型的成员变量threadlocals来存储实际变量的副本。K为当前ThreadLocal变量,V为变量的副本。初始时,Thread里面的线程为空,当ThreadLocal变量调用set或者get方法时,就会完成对threadlocals进行初始化。在当前线程里面,如果要使用副本变量,可以通过get方法在threadlocals里面查找。

怎样用wait-notify方法来解决生产者-消费者问题?

思路:在同步块中调用wait和notify方法,如果阻塞,通过循环来测试等待条件。

用Java写一个线程安全的单例模式

线程安全即初始化是在多线程环境中,仍能保证单例。用枚举类是最简单实现创建线程安全的单例模式。

public static SingletonThreadSafe getInstance(){

if (singletonThreadSafe == null){

synchronized (SingletonThreadSafe.class){

new SingletonThreadSafe();

}

}

return singletonThreadSafe;

}

//然而在多线程下,存在指令重排序问题,因此可以设置singletonThreadSafe为volatile

sleep()方法和wait()方法区别

两者都是暂停当前运行的线程。区别在于sleep()方法不会释放锁,而wait()方法意味着等待条件,一般在循环体中,该方法需要释放锁。只有这样其他线程才能在满足条件的时候获得锁。

什么是不可变对象(immutable object)?如何创建不可变对象

一旦对象被创建,状态就不能再改变。任何修改都会创建一个新的对象。如String,Integer等包装类。

我们能创建一个包含可变对象的不可变对象吗?

当然啦。需要注意的是不要共享可变对象的引用,需要改变时就返回原对象的一个拷贝。例 : 对象中包含一个日期对象的引用。

Java中应该用什么数据类型代表价格?

BigDecimal.如果有性能和内存方面的考虑可以使用预定义精度的double

怎样将byte转换为String

new String(byte)     //注意编码格式

怎样将bytes转换为long

String接收,在Long.ParseLong()

能将int强制转换为byte类型吗?大于byte范围将会什么现象?

可以。高24位将会被丢弃。byte范围 -127-128

存在两个类,B继承A,C继承B,能将B转换为C吗?C=(C)B

可以。不过容易出现类型转换异常。

哪个类包含clone方法,是Cloneable还是Object

java.lang.Cloneable是一个标识性接口,不包含任何方法,clone方法在Object中定义,是一个native方法

Java中的++操作是线程安全的吗?

不是。并非原子操作

a = a + b 和 a += b有什么区别?

+=隐式的将操作结果类型转换为持有的结果类型。

byte a = 127;

byte b = 127;

b = a + b; // error : cannot convert from int to byte

b += a; // ok

能在不强制转换的情况下将一个double类型赋值给long吗?

不能,double的类型比long更广

3*0.1 == 0.3将会返回true还是false

false,有些浮点数不能精确的表示出来(巨坑。。MD。。可以转换成二进制看)

int和Integer哪个会占更多的内存

Integer。包装类,也要保存对象

为什么Java中的String要设计成不可变(Immuable)

使用太频繁,设置不可变,方便多客户端共享

能在switch中使用String吗?

Java 7开始可以。语法糖,内部实现case中使用的是String的hashCode

Java中的构造器链是什么?

当从一个构造器中调用另一个构造器时. 只有重载了 构造器才会出现

64位JVM中,int长度是多少

4个字节,32位。与平台无关。

Serial 与 Parallel GC之间的不同之处

两者在GC执行的时候都会stop-the-world. Serial默认是复制收集器。Parallel使用多个GC线程来执行。

Java中WeakReference与SoftReference区别

Java中一共有4种引用类型:

StrongReference:强引用,new出来的对象,只要引用存在,就不会给GC回收

SoftReference:软引用,只有即将发生OOM的时候会被回收

WeakReference:弱引用,只要有GC就会被回收

PhantomReference:虚引用,或者幽灵引用,被回收的时候仅仅收到系统通知以下。

WeakHashMap是怎样工作的?

与正常的HashMap相似,但是是以弱引用作为key,意思是key对象没有任何引用的时候,key/value就会被回收

JVM选项 -XX:+UserCompressedOops什么用,为什么要用

应用从32位JVM迁到64位JVM时,由于对象的指针从32位增加到了64位,因此堆内存会突然增加,差不多要翻倍。此选项用于压缩,使用32位OOP而不是64位

怎样通过Java判读JVM是62位还是64位?

可以检查某些属性如sun.arch.data.model或者os.arch来获取信息

32位JVM和64位JVM最大堆内存是多少?

32位是2^32次方,4G..64位无限制。

JRE,JDK,JVM,JIT之间有什么不同

JIT(Just In Time Compilation)即时编译,当代码执行超过一定的阈值的时候,会将字节码编译成本地代码。

解释Java堆空间及GC

Heap:所有线程共享,JVM启动是分配,对象创建的时候从堆中分配内存。GC是JVM的一个进程,回收无用对象内存,用于将来的分配。

能保证GC执行吗?

不能,虽然可以调用System.gc(),或者Runtime.getRunTime().gc(), 但是没有办法保证执行

怎样获取Java程序使用的内存?堆使用的百分比

可以通过 java.lang.Runtime 类中与内存相关方法来获取剩余的内存,总内存及最大堆内存。通过这些方法你也可以获取到堆使用的百分比及堆内存的剩余空间。Runtime.freeMemory() 方法返回剩余空间的字节数,Runtime.totalMemory() 方法总内存的字节数,Runtime.maxMemory() 返回最大内存的字节数

Java中堆和栈有什么区别

堆:线程共享,存放Java对象     栈:线程私有,保存方法栈帧和局部变量

a==b 和 a.equals(b)有什么区别?

a.hashCode()有什么用?与a.equals(b)有什么关系?

hashCode()方法是相应对象整形的hash值。常用于基于hash的集合类,如Hashtable,HashMap,LinkedHashMap。依据Java规范,使用equals方法判断相等的对象必有相同hash值

final,finally,finalize有什么不同

final,finally略。finalize:Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。该方法是有GC在确定这个对象没有被引用时调用,但是什么时候调用finallize没有保证。

Java的编译器常量是什么?使用它有什么风险

即公告静态不可变量 public static final . 在编译的时候会被替换掉。 弊端:当时用一个内部的或者第三方库中的共有编译常量,但是这个值被后面的人改了,但是客户端仍然在使用旧值。为避免,在更新依赖Jar文件时,确保重新编译程序。

List,Set,Map,Queue之间的区别。

List:元素间保持一定的顺序

Map:键值对

Queue:FIFO

poll()方法和remove()方法的区别

都是从队列中取出一个元素。poll()获取失败时会返回空,remove失败时会抛出异常。

Java中LinkedHashMap和PriorityQueue的区别是什么

PriorityQueue保证最高或者最低优先级的元素总是在队列的头部,LinkedHashMap维持的顺序是插入时候的顺序。当遍历一个PriorityQueue时没有任何顺序保证,但LinkedHashMap是插入时候的顺序

ArrayList和LinkedList的区别

ArrayList底层是维持的数组,支持随机访问,而LinkedList底层是连表,不支持随机访问。使用下标访问一个元素,ArrayList时间复杂度是O(1),而LinkedList是O(n)

用哪两种方法实现集合的排序

使用有序集合,如TreeSet和TreeMap。

也可以使用有顺序的集合,如list,然后通过Collections.sort()来排序

Java如何打印数组

Arrays.toString()

Java中的LinkedList是单项链表还是双向?

双向链表。

Java中的TreeMap是采用什么实现的

红黑树

Hashtable与HashMap区别

Hashtable采用同步,HaspMap没有。Hashtable不允许有空的key,HashMap的key可以为null

Java中的HashSet,内部是如何工作的?

HashSet内部采用HashMap来实现。由于Map需要key和value,每一个key都有一个默认的value,类似于HashMap,HashSet不允许重复的key,只允许一个null key,级Hash只允许存储一个null对象。

写一段代码,在遍历ArrayList时移除一个元素

(大坑,需要看源码) 一般使用循环遍历的时候,ArrayList是使用数组实现。删除元素时需要涉及到数组的移动,在遍历元素时,由于该元素符合删除条件,将该元素从数组中删除,并将后一个元素移动至当前位置,导致下一次遍历时没有遍历到,因此无法删除。使用foreach增强遍历时,实际上是Iterable,hasNext,next()元素的简写,在fastRemove()方法中,可以看到将一行modCount值加一,但是在ArrayList返回的迭代器中会做修改次数检查。

//倒叙遍历

public static void remove(ArrayList list) {

for (int i = list.size() - 1; i >= 0; i--) {

String s = list.get(i);

if (s.equals("bb")) {

list.remove(s);

}

}

}

//使用迭代器Iterator的remove方法

public static void remove(ArrayList list) {

Iterator it = list.iterator();

while (it.hasNext()) {

String s = it.next();

if (s.equals("bb")) {

it.remove();

}

}

}

能自己写一个容器实现类,实现一个for-each循环吗?

可以。如果想要使用增强遍历,就要实现Iterable接口。如果实现Collection接口,就默认有该属性

HashMap和ArrayList默认大小是多少

16和10

ArrayList

HashMap 必须是2的整数次方

有没有可能两个不等的对象有相同的hashCode

有可能。两个相等的对象必须有相同的hashCode值,反之没规定

可以在hashCode中使用随机数吗?

不能。对象的hashCode的值必须是相等的。

Java中Comparator与Comparable有什么不同

Comparable用于定义对象的自然顺序,Comparator常用来定义用户指定的顺序。Comparable只能有一个,可以有多个Comparator来定义对象的顺序。

为什么重写equals时候,必须要重写hashCode方法

强制规范必须同时重写,许多hash类容器都依赖于hashCode与equals规定

在Java程序中有三个Socket,需要多少个线程来处理

如果是阻塞,则必须一个线程连接一个socket,非阻塞则不是

Java中怎样创建byteBuffer

ByteBuffer.allocate(int capacity)     //创建一个指定capacity的ByteBuffer

ByteBuffer.allocateDirect(int capacity)     //创建一个Direct的byteBubyteffer,在与IO操作交互的时候性能较好

ByteBuffer.wrap(byte[] array)

ByteBuffer.wrap(byte[] array,int offset,int length)     //将一个byte数组或者数组的一部分包装成byteBuffer

Java采用的是大端还是小端?

大端

ByteBuffer中的字节序是什么

字节序:字节存放的顺序。大端 BIG-ENDIAN

Java中直接缓冲区与非直接缓冲区的区别

直接缓冲区可以通过allocateDirect方法来创建,也可以通过内存映射来创建,如果是直接缓冲区JVM会尽最大努力直接在此缓冲区上执行本机的I/O操作

非直接缓冲区写入步骤

创建一个临时的ByteBuffer对象

将非直接缓冲区的内容复制到临时缓冲区中

用临时缓冲区执行低层次I/O

临时缓冲区对象离开作用域,并最终成为被回收的无用数据

如果采用直接缓冲区会减少一次复制的过程,如果需要使用循环缓冲区,用直接缓冲区可以很大提高性能。虽然直接缓冲区可以使JVM更高效的I/O操作,单使用的内存是系统分配的,绕过了虚拟机堆栈,建立和销毁笔堆栈上的缓冲区要更大的开销。

Java中内存映射缓冲区是什么

?就是不全部加载到内存里面..

socket选项TCP NO DELAY是什么

有包头立即被发送。TCP_CORK组包

TCP协议与UDP协议有什么区别

Java中ByteBuffer与StringBuffer有什么区别

Java中编写多线程的时候有哪些最佳实践

给线程命名,方便调试

最小化同步的范围,而不是将整个方法同步,只对关键部分做同步

多使用volatile而不是synchronized

使用高层次的并发工具而不是使用wait() notify()方法来实现线程间通信。如BlockingQueue,CountDownLatch,Semeaphore

优先使用并发集合,而不是对集合进行同步

说出几点Java中使用Collections的最佳实践

如果不需要同步使用ArrayList而不是Vector

优先使用并发集合,而不是对集合进行同步

使用接口代表访问集合,如使用List存储ArrayList,用Map存储HashMap

用迭代器来循环集合

使用集合的时候使用泛型

在Java中使用线程的最佳实践

对线程命名

将线程和任务分离,使用线程池来执行Runnale或者Callable

使用线程池

说出5条IO最佳实践

IO对性能非常重要,在应用的关键路径上避免I/O操作。

使用带缓冲区的IO类,而不要读取字节或者字符

在finally中关闭流

使用内存映射文件获取更快的IO

JDBC的最佳实践

使用批量操纵插入和更新数据

使用PreparedStatement来避免SQL异常,并提高性能

使用数据库连接池

通过列名来获取结果集,而不是下标

Java中重载的最佳实践

不要一个方法接收int参数,另外几个接收Integer类型

不要重载参数一致,只是参数顺序不一致

参数多余5个,可以使用可变参数

在多线程下,SimpleDateFormat是线程安全的吗?

不是。需要给simpleDateFormat对象加锁(不建议,影响性能),或者放在方法里面随用随new,或者LocalThread里面

Java中,怎么在格式化的日期中显示时区

参数后加Z

Java中java.util.Date与java.sql.Date有什么区别

java.util.Date针对SQL语句,只有日期,没有时间。都有getTime方法返回毫秒数。java.sql.Date继承于java.sql.Date. 在读写数据库时,PreparedStament的setDate和ResultSet的getDate方法第二个参数都是。

如何计算两个日期之间的差距

public long  dateDiff() {

Date date1 = new Date();

Date date2 = new Date();

long n1 = date1.getTime();

long n2 = date2.getTime();

long diff = Math.abs(n1 - n2);

diff /= 3600*1000*24;

return diff;

}

Java中如何将字符串转换为日期

SimpleDateFormat的parse方法。

public static Date string2Date(String date) {

// 创建日期格式化对象

SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);

Date returnDate = null;

try {

// 日期格式化对象将日期字符串转换为日期对象

returnDate = df.parse(date);

} catch (ParseException e) {

log.error("String to date error!date=" + date, e);

return returnDate;

}

return returnDate;

}

单元测试

如何测试一个静态方法

可以使用PowerMock库来测试

怎样用Junit来测试一个方法的异常

都有哪些单元测试库

@Before和@BeforeClass有什么区别?

怎样检测一个字符串只包含数字?

public static boolean check(String string){

try {

int num = Integer.valueOf(string);

return true;

} catch (NumberFormatException e) {

return false;

}

}

Java中如何利用泛型写一个LRU缓存

http://blog.csdn.net/beiyeqingteng/article/details/7010411

写一段Java代码将byte转换为long

强制转换?

byte b = 123;

long l = (long)b;

在不使用StringBuffer情况下怎样反转字符串

public String reversal(String src) {

byte[] bytes = src.getBytes();

Stack stack = new Stack();

String string = null;

for (int i=0;i

stack.push(bytes[i]);// stack

}

for (Object object : stack) {

System.out.println(object);

}

return string;

}//写入栈,先进后出

Java中如何统计某一个单词出现的频率

public static void display(File file) throws Exception {

BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

String line = null;

TreeMap treeMap = new TreeMap<>();

while ((line = bufferedReader.readLine()) != null) {

line.toLowerCase();

String reg1 = "\\s+";

String reg2 = "^[a-zA-Z]\\w*";

String str[] = line.split(reg1);//分词

for (String s : str) {

if (s.matches(reg2)) {

if (!treeMap.containsKey(s)){//匹配单词

treeMap.put(s,1);

}

else{

treeMap.put(s,treeMap.get(s)+1);

}

}

}

}

System.out.println(treeMap);

}

如何检查出两个给定的字符串是反序的

if(str1.length() != str2.length()){

return false;

}

String strTemp = str1.reversal();

if(strTemp.equals(str2)){

return true;

}

return false;

打印出数组中的重复元素

public class RepetitiveElements {

public static void main(String[] args) {

int[] arr = new int[]{1, 2, 3, 4, 5, 1, 3, 5};

Set set = new HashSet();

for (int i = 0; i < arr.length; i++) {

for (int j = 0; j < arr.length; j++) {

if (i != j && arr[i] == arr[j]) {

set.add(arr[i]);

}

}

}

System.out.println("重复的数字:" + set.toString());

}

}

Java中如何将字符串转换为整数

int num = Integer.valueOf(str);

return num;

在没有使用临时变量的情况下如何交换两个整数变量的值

//用栈

int a = 2;

int b = 3;

Stack stack = new Stack();

stack.push(a);

stack.push(b);

a=(int)stack.pop();

b=(int)stack.pop();

OOP

接口是什么,为什么要使用接口而不是具体实现类

略。Java8种可以在接口中声明静态的默认方法

抽象类与接口有什么不同

一个类只能继承一个父类,但是可以实现多个接口。抽象类必须被继承不能new. 接口主要定义类的类型,有助于实现多态机制。

里氏替换原则

子类可以拓展父类的功能,但不能改变父类的原有功能

子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法

子类可以增加自己的特有方法

子类重载父类的方法时,方法的前置条件(方法的形参) 要比父类方法的输入参数更宽松。

当子类的方法实现父类的抽象方法时,方法的后置条件(返回值)要比父类更严格。

什么情况下会违反迪米特法则?为什么会有这个问题

低耦合。

适配器模式是社么?什么时候用。

适配器模式对外提供接口的转换。如果客户端使用的是某些接口,但是我有两外的一些接口,可以写一个适配去连接这些接口。

什么是依赖注入和控制反转

构造器注入和setter注入,那种方式更好

构造器注入保证所有的注入都会被初始化。但是setter注入保证更好的灵活性来设置可选依赖。用XML描述:Setter可读性更强。强制依赖选择构造器,可选依赖选择setter

依赖注入和工厂模式之间有什么不同

都是讲对象的创建从应用的逻辑中分离,依赖注入比工厂模式更清晰,通过依赖注入,你的类就是POJO,它只知道依赖而不关心它们怎么获取。使用工厂模式,你的类需要通过工厂来获取依赖。

适配器模式和装饰模模式有什么区别

适配器模式用于桥接两个接口。装饰模式的目的在于不修改类的情况下给类增加新的功能。

适配器模式和代理模式有什么区别

代理模式是增加一个额外的中间层,以便支持分配,控制,或者只能访问

什么是模板方法模式

抽象类,子类继承复用

什么时候使用访问者模式

什么时候用组合模式

继承和组合之间有什么不同

两者都可以实现代码复用,但是组合比继承更灵活,因为组合运行在运行时选择不同的实现。

重载和重写

都允许使用相同的名称来实现不同的功能,重载是编译时期的活动,重写是运行时期的活动。可以在同一个类中重载方法,只能在子类中重写方法。重写必须要有继承。

Java中嵌套的公共静态类与与顶级类有什么区别

类的内部可以有多个嵌套的公共静态类。但是一个源文件只有一个顶级公共类,且必须与源文件名称一致。

OOP中组合,聚合,关联有什么区别

关联:两个类彼此之间有关系,就是彼此相关联。组合是比聚合更强的关联。组合中,一个对象是另一个对象的拥有者,而聚合是一个对象使用另一个对象。

开闭原则

一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。

抽象工厂模式和原型模式区别

享元模式

享元模式通过共享对象来避免创建过多的对象。为了使用享元模式必须保证对象是不可变的。如JDK中String池,Long池,Integer池等。

正则表达式

?待加强学习

Java中受检查异常和不受检查异常的区别

受检查异常:编译器在编译期间检查,必须通过强制处理或者throw子句中声明。

非受检查是RuntimeException的子类,在编译阶段不受编译器的检查。

Java中,throw和throws区别

throw用于抛出一个java.lang.Throwable类的实例化异常。可以用关键字throw抛出一个error或者exception. 如throw new IllegalArgumentException(“size must be multiple of 2″). 而throws作为方法签名的一部分,方法抛出相应的异常以便调用者能够处理。Java中,任何未处理的受检查异常强制在throws子句中声明。

Java中Serializable与Externalizable区别

Serializable接一个序列化Java类的接口,是JVM默认的序列化方式,以便于在网络上传输或者将他们的状态保存在磁盘上,成本高,脆弱,不安全。Externalizable允许控制整个序列化过程,指定特定的二进制格式,增加安全机制。

Java中DOM和SAX解析器有什么不同

DOM解析器将整个XML文档加载到内存中创建一个DOM模型树,可以更快的查找结点和修改XML结构。SAX是基于事件的解析器,不会将整个DOM文档加载到内存。因此DOM笔SAX更快,但也消耗更多内存,不适合解析大的XML文档。

为什么线程通信的方法wait(),notify(),notifyAll()被定义在Object类里

Java中每个对象都有一个锁(monitor, 也可以称为监视器) 并且wait(), notify()等方法用于等待对象的锁或者通知通知其他对象的监视器可用. 在Java对象中并没有可提供任何对象使用的锁和同步器. 因此这就是为什么这些方法是Object类的一部分,这样Java的每一个类都有用于线程间通信的基本方法.

为什么wait(),notify(),notify()方法都必须在同步方法或者同步块中被调用

当一个线程需要调用对象的wait()方法的时候, 这个线程必须必须拥有该对象的锁, 接着它会释放这个对象锁,并进入等待状态直到其他线程调用这个对象上的notify()方法. 同样,当一个线程需要调用对象的notify()方法时,会释放这个对象的锁.以便其他在等待的线程可以得到这个对象锁..由于所有这些方法都需要线程持有对象的锁,这样只能通过同步来实现. 因此只能在同步方法或者同步代码块中使用.

你可能感兴趣的:(你们搞的这个Java啊,Excited!)