记录自己面试过程中遇到的Java相关面试题。欢迎大家前来交流!
1.如何实现一个int型整数乘8?
1.int y = x * 8;
2. int y = x << 3;(逻辑左移,8 = 2的3次方)
这种题一问出来就知道是陷阱。
事实上在大数字方面的计算左移的效率要比直接乘高很多。
2.Java的三大特性?
1.封装:把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。
2.继承:继承使得你可以定义一个通用的类(父类),之后扩展该类为一个更加特定的类(即子类)。
3.多态:多态意味着父类的变量可以指向子类对象。
3.重载,重写的区别?
1.重写,子类从父类中继承方法,需要修改父类的方法,称作方法重写。
2.重载方法名相同,而这些方法的参数个数及类型不能完全相同。
4.volatile关键字?
修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。
5.单例模式?
确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
组成元素:
1.私有的构造方法。
2.指向自己实例的私有静态引用。
3.以自己实例为返回值的静态的公有的方法。
6.反射机制?
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种
动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
7.StringBuilder与StringBuffer?
StringBuilder与StringBuffer创建可改变字符串.
单任务访问StringBuilder更有效。
StringBuffer具有同步修改缓冲区的方法,意味着只有一个任务被允许执行方法之外,适用与多任务并发访问。
通常情况下,StringBuilder与StringBuffer都可以相互替代。
1.Java中对象什么时候被回收?
对象是否被引用。也就是说如果对象处于不可到达状态就会被回收掉。
理论上:每个对象都有一个引用计数器。引用接至对象,计数+1引用离开作用域或被置为null,计数-1.
垃圾回收器会在含有全部对象的列表上遍历,当某个计数为0.释放器占用空间。
2.Java垃圾回收算法?
1.复制:把空间A的可到达对象全部复制到B空间然后回收A空间。
缺点:需要巨大的复制成本和较多内存.
2.标记清除:遍历标记所有被引用的可达对象,然后遍历内存区域,清除回收没有被标记从对象。
缺点:两次遍历需要较大遍历成本和造成堆内存碎片较多。
3.标记压缩:遍历标记所有被引用的可达对象,把他们标记可达到状态后把这些对象搬到一起,这个过程为内存压缩,然后垃圾回收机制
再次回收那些不可到达对象所占用的空间。
4.分代回收:根据一个对象生存时间的长短,再根据不同代采取不同的垃圾回收策略。
首先把堆分成3个代:Young,Old,Permanent Young采用复制算法——频率比较高,Old采用标记压缩——频率比较低,Permannet不用回收。
3.Java四种对象引用的分类和区别?
1.强引用:JVM不会回收强引用所引用的Java对象,可能会导致内存泄露
2.软引用:系统内存空间足够不会回收,不够才回收。
3.弱引用:每次垃圾回收机制执行都会回收。
4.虚引用不影响对象的生命周期。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都能被垃圾回收器回收。
4.Java怎么样进行内存分配?
1.栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容。
2.堆中存放使用new关键字创建的对象。
3.静态区存储类中所有的静态变量。
4.字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,
存放在字符串常量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。
5.sleep()与wait()的区别?
1.调用sleep()方法后,当前线程进入休眠期,暂停执行,让出cpu给其他线程,并不会释放对象锁。到达休眠时间后线程将继续执行,
直到完成。
2.调用wait()方法后,当前线程会放弃对象锁,进入等待队列,需要等待其他线程调用notify或者notifyAll唤醒等待线程池中的线程。
6.Java线程池技术?
类型 | 说明 | 特点 |
---|---|---|
SingleThreadExecutor | 单一线程的线程池 | 只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。 |
FixedThreadPool | 固定大小的线程池 | 可控制线程最大并发数,超出的线程会在队列中等待。 |
CachedThreadPool | 可缓冲的线程池 | 如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 |
ScheduledThreadPool | 无限制大小线程池 | 支持定时及周期性任务执行。 |
7.java中的main方法必须写成static的原因?
在类加载时无法创建对象,而静态方法可以不通过对象调用,所以在类加载时就可以通过main方法入口来运行程序。
8.接口类与抽象类的区别?
参数 | 抽象类 | 接口 |
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类的区别 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
9.Java匿名内部类?
匿名内部类也就是没有名字的内部类,所以匿名内部类只能使用一次,它通常用来简化代码编写。
前提条件:匿名内部类不能是抽象的,必须继承一个父类或实现一个接口。
1.Java作用于修饰符?
private:表示私有字段,或者方法等,只能从类内部访问
protected:表示字段只能通过类或者其子类访问,子类或者在同一个包内的其他类
public:表示共有属性或者方法
2.接口类可以继承接口类吗?
可以。如下代码,Two继承One后,实现Two的同时也要实现One:
public interface One {
void get(int a);
}
public interface Two extends One {
void put(int b);
}
public class Main implements Two {
@Override
public void put(int b) {
}
@Override
public void get(int a) {
}
}
3.树与图的区别?
树和图都是非线性的数据结构。图相对于树来说,是更加抽象和复杂的。可以认为树
是图的基础,树是一种更简单意义上的图。
在树型结构中,每一个数据元素都可能和下一层中多个元素(即孩子结点)相关,
但却只能与上一层中的一个元素(即双亲结点)相关。而在图形结构中,结点之间
的关系可以是任意的,图中任意两个数据之间都可能相关。
1.Map中的key可以为空吗?
可以。HashMap。
2.List遍历的几种方式?
1. 普通for循环://内部不锁定,效率最高,但在多线程要考虑并发操作的问题。
for( int i = 0 ; i < list.size() ; i++) {
}
2. 增强for循环://其内部实质上还是调用了迭代器遍历方式,这种循环方式还有其他限制,不建议使用。
for(String str : list) {
}
3.迭代器遍历://执行过程中会执行数据锁定,性能稍差,若在循环过程中要去掉某个元素只能调用iter.remove()方法。
Iterator<String> iter = list.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
Java中eqauls和hashCode的区别?
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2、如果两个对象不equals,他们的hashcode有可能相等。
3、如果两个对象hashcode相等,他们不一定equals。
4、如果两个对象hashcode不相等,他们一定不equals。