常见Java笔面试题集(七)
常见Java笔面试题集(七)
1.阐述静态变量和实例变量的区别。
答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
2.获得一个类的类对象有哪些方式?
答:
- 方法1:类型.class,例如:String.class
- 方法2:对象.getClass(),例如:"hello".getClass()
- 方法3:Class.forName(),例如:Class.forName("java.lang.String")
3.Java 中会存在内存泄漏吗,请简单描述。
答:内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。但是java中有垃圾回收机制,它能够将不再被使用的对象,自动从内存中清除。即使这样,java中也存在着内存泄漏的情况:
一:当长生命周期的对象持有短生命周期的对象的引用,就很可能发生内存泄漏。尽管短生命周期的对象已经不再需要,但是长生命周期的对象一直持有它的引用导致其无法被回收。例如,缓存系统;加载一个对象放在缓存系统中,一直不去使用这个对象,但是它一直被缓存引用,所以不会被回收导致缓存泄漏。
检查java中的内存泄漏,一定要将程序各个分支情况都完成执行至结束,然后看其是否被使用过,如果没有才能判定这个对象属于内存泄漏。
二:当一个对象被存储进HashSet集合中,就不可修改这个对象中用于计算哈希值的属性了。否则,对象修改后的哈希值与刚添加进HashSet集合时的哈希值不一样,此时如果将当前对象的引用作为参数,用contains方法判断对象是否存在,则会返回找不到对象的结果。这会导致无法从HashSet单独删除当前对象,造成内存泄漏。
4.如何实现字符串的反转
简单的字符串反转:
public static String reverse(String originStr) {
if(originStr == null || originStr.length() <= 1)
return originStr;
return reverse(originStr.substring(1)) + originStr.charAt(0);
}
字符串内单词的反转:
public String ReerseSentence(String[] str){
if(str == null || str.length() == 0)
return str;
if(str.trim().length() == 0)
return str;
StringBuilder sb = new StringBuilder();
String[] stre = str.split(" ");
for(int i = stre.length()-1; i > 0; i--){
sb.append(stre[i] + " ");
}
sb.append(stre[0]);
return String.vauleOf(sb);
}
5.面试题 - 编程实现文件拷贝
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public final class MyUtil {
private MyUtil() {
throw new AssertionError();
}
public static void fileCopy(String source, String target) throws IOException {
try (InputStream in = new FileInputStream(source)) {
try (OutputStream out = new FileOutputStream(target)) {
byte[] buffer = new byte[4096];
int bytesToRead;
while((bytesToRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
}
}
}
}
6.简述一下你了解的设计模式
答:设计模式:
- 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
- 代理模式:给一个对象提供一个代理对象,并由代理对象控制原对象的引用。
- 工厂模式:工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。
- 观察者模式:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,这个主题对象在状态发发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
- 适配器模式:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而能使原本因接口不匹配而无法一起工作的两个类能够一起工作。
手写单例模式
//懒汉式 (线程安全的)
public class SingleTon{
private static SingleTon instance;
private SingleTon(){}
public static synchronized SingleTon getInstance(){
if(instance == null){
instance = new SingleTon;
}
return instance;
}
}
//饿汉式(线程不安全)
public class SingleTon{
private static SingleTon instance = new SingleTon();
private SingleTon(){}
public static SingleTon getInstance(){
return instance;
}
}
7.网络层的ARP协议的工作原理
答:网络层的ARP协议完成了IP地址与物理地址的映射。首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包中包含源主机的IP地址,硬件地址以及目的主机的IP地址。网络中所有的主机接收到这个ARP请求后,会检查数据包中的目的IP地址是否和自己的IP地址一致。如果不相同就忽略此数据包,如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP列表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址,源主机收到这个ARP响应数据包后,将得到目的主机的IP地址和MAC地址添加到自己ARP列表中,并利用此信息开始数据传输,如果源主机一直没收到ARP响应数据包,表示ARP查询失败。
8.在进行数据库编程时,连接池有什么作用?
答:由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立连接都需要进行TCP的三次握手,释放连接需要进行TCP四次握手,造成的开销是不可忽视的),为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销。
9.什么是事务,什么是锁?
答:事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前的状态,或者是上一个节点,为了确保要么执行,要么不执行,就可以使用事务。要将一组语句作为事务考虑,就要通过ACID测试,即事务的 原子性,一致性,隔离性,持久性。
锁是实现事务的关键,所可以保证事务的完整性和并发性,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。
10.事务的ACID是指什么?
答:
- 原子性(Atomic):事务中各项操作,要么全部提交成功,要么全部失败回滚,任何一项操作的失败都会导致整个事务的失败;
- 一致性(Consistent):事务结束后系统状态是一致的;
- 隔离性(Isolated):并发执行的各个事务之间不能相互干扰,一个事务所做的修改在最终提交之前,对其他事物不可见。
- 持久性(Durable):一个事物一旦提交,它对数据库中的数据改变是永久性的,即使系统崩溃,修改的数据也不会改变。通过日志和同步备份可以在故障发生后重建数据。
下一篇: 0520面试题拓展