【面试】Java基础篇(一)

一、Java概念原理

1、Java中为什么要写None Static Method(非静态方法/实例化方法)?

答:静态方法常驻内存,定义太多会占用大量资源,可能导致溢出,而非静态方法随着实例对象被回收后消失,同时代码不会共享,线程安全

  • 补充:
角度Static MethodNon Static Method
生命周期与静态类成员一样,装载进内存会常驻,直至JVM关闭实例化后才分配内存,必须通过类实例引用,当实例对象被JVM回收后,跟着消失
内存位置静态方法与静态变量创建后使用同一块内存,连续存在内存多个地方,离散
效率
线程安全静态方法(变量)共享代码(数据)段,有并发问题针对确定对象,没问题

追问1:Java 高级特性?

  • 1)泛型:参数化类型,即把数据类型变成一个可变参数。

  • 2)反射:通过 名称来得到对象(类、属性、方法) 的技术。
    如:可通过类名-->生成类实例;方法名-->调用方法;属性名-->访问属性值。

  • 3)注解:对Java代码打标签,说明作用。
    如:读懂代码、格式检查、减少配置、减少重复。可以在编译期检测,也可以运行时反射。

2、动态代理是基于什么原理?【第6讲】(运行时自省,获取类声明属性和方法)

答:反射赋予程序在运行时自省(introspect)的能力,可以直接操作类或者对象,如获取类定义、属性和方法,甚至可以运行时修改类定义。

动态代理是一种运行时动态构建代理、处理代理方法调用的机制。利用类似机制的场景有 RPC 调用、AOP。

实现方式方面,JDK 自身提供的利用了反射机制,其他的有更高性能的字节码操作机制,类似 ASM、cglib(基于 ASM)、Javassist 等。

3、Java为什么不能多继承?

答:多继承指一个类同时从多个父类那继承行为和特征。图中X方法继承哪个类的方法呢?容易导致事故。
1

追问1:如何实现多继承?

答:接口或内部类。

4、谈谈接口和抽象类有什么区别?【第13讲】(*3)

  • 1)接口是行为的抽象,是抽象方法的集合,可以利用接口达到API定义和实现分离的目的。
  • 2)抽象类是不能实例化的类,形式上和一般类没区别,主要是为了代码重用。Java标准库(如collection框架)中很多通用部分(方法实现或成员变量)就被抽取成为抽象类。
接口说明:
1. 不能实例化,不能包含任何非常量成员,任何field都隐含public static final2. 没有非静态方法实现,只能是抽象或静态方法。接口举例:java.util.List[Java标准库]

// 实现interface用implements关键词,继承abstract class用extends关键词。
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//...
}

5、什么是内部类,什么是匿名内部类?

  • 1)内部类:将一个类的定义,放在另一个类的定义内部。内部类继承自某个类或实现某个接口,操作外围类的对象。
  • 2)匿名内部类:没有名字的内部类。只能使用一次(因为没名字),常用来简化代码编写,
  • 3)匿名类使用前提:必须继承一个父类或实现一个接口。
    5

6、重写和重载的区别。(*2)

1)含义

  • 重写:子类对父类的方法进行重新实现。即外壳不变,核心重写
  • 重载:每个重载方法(或构造函数)都必须有独一无二的参数类型列表
    2

2)比较

区别点重写重载
参数列表一定不能修改必须修改
返回类型一定不能修改可以修改
异常可以减少或删除,一定不能抛出新的或更广的异常可以修改
访问一定不能做出更严格的限制,可以降低限制可以修改
类型动态绑定,运行时确定静态分配,类加载时确定

追问1:多态含义?

  • 1)含义 & 作用
    多态是同一个行为(接口、消息)可根据对象不同而采取多种不同行为。能消除类型间耦合,具有良好的可扩展性。

7

  • 2)实现方式 & 必要条件
    实现方式:重写、接口(插座)、抽象类和抽象方法。
    三个必要条件:继承、重写、父类引用指向子类对[ Parent p = new Child(); ]
// 例1:
package objectandclass;  
	class A {    
		public void show(D obj){    
			System.out.println("A and D");  
		}     
		public void show(A obj){    
	    	System.out.println ("A and A");    
		}     
	}     
	class B extends A{    
		public void show(B obj){    
			System.out.println("B and B");    
		}    
		public void show(A obj){    
			System.out.println("B and A");    
		}     
	}    
	class C extends B{}     
	class D extends B{}    
}

... { 
	A a1 = new A();    
	A a2 = new B();    
	B b = new B();    
	C c = new C();     
	D d = new D();     
	a1.show(b);  // A and A
	a1.show(c);  // A and A
	a1.show(d);  // A and D
	a2.show(b);  // B and A
	a2.show(c);  // B and A
	a2.show(d);  // A and D
	b.show(b);   // B and B
	b.show(c);   // B and B
	b.show(d);   // A and D
}

7、Exception和Error有什么区别?【第2讲】:Throwable类;可预料VS不可恢复;可检查+不可检查

1)相同

  • Exception和Error都继承了Throwable类,只有Throwable实例可被抛出(throw) 或捕获 (catch)。
    9

2)解释

  • Exception是可预料的意外情况,可能且应该被捕获处理;
  • Error是正常不太可能出现的情况,大部分出现会导致程序(如JVM)处于不可恢复异常状态,不便于也不需捕获。

3)Exception分类

  • Exception分为可检查异常和不可检查异常,可检查异常在源代码中必须显式地进行处理,这是编译期检查的一部分;不检查异常(NullXXX、ArrayIndexOutofBoundsXXX),通常是可避免的逻辑错误,根据需要捕获。

追问1:你了解哪些 Error、Exception 或者 RuntimeException?

……

追问2:NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

NoClassDefFoundError是一个错误(Error),而ClassNOtFoundException 是一个异常。

  • 1)NoClassDefFoundError:编译时存在,JVM或ClassLoader实例加载(正常调用或new新对象)时找不到类定义,那此时会抛出NoClassDefFoundError;
  • 2)ClassNotFoundException:动态加载类在类路径中没找到,此时会抛出ClassNotFoundException异常。

追问3:异常处理有哪些原则?

1)捕获特定异常。 尽量不要捕获通用异常,如 Exception。【基本】
2)不要生吞异常。 可能导致难诊断的诡异情况。【基本】
3) Throw early, catch late 原则。

补充:
1. 不捕获某些异常。如RuntimeException 被扩散出来,而不是被捕获。除非深思熟虑,否则不要捕获 Throwable 或者 Error,这样很难保证我们能够正确程序处理 OutOfMemoryError2. 分布式系统最好使用产品日志,详细地输出到日志系统里,printStackTrace()无法找到堆栈轨迹(stacktrace)。

8、谈谈final、finally、 finalize有什么不同?【第3讲】(*2)

  • 1)final可以修饰类/变量/方法,代表不可继承/修改/重写
  • 2)finally保证重点代码一定执行的一种机制。如try-catch-finally关闭JDBC连接、unlock锁
  • 3)finalize为了保证对象在垃圾收集前完成特定资源的回收。JDK 9标记弃用。

追问1:final与immutable相同吗?

答:不等同,只保证对象引用不可赋值,但对象行为(如添加)不被影响。

 final List<String> strList = new ArrayList<>();
 strList.add("Hello");
 strList.add("world");  
 List<String> unmodifiableStrList = List.of("hello", "world");  // List.of本身不可变
 unmodifiableStrList.add("again");  // 会抛出错误
 
说明:
final 只约束 strList 引用不可被赋值,但 strList 对象行为不被 final 影响,添加等操作正常。若希望对象本身不可变,需要相应类支持不可变行为。

9、String、StringBuffer、StringBuilder有什么区别?【第5讲】(*3)不可变,中间对象;线程安全;非线程安全

String 提供构造和管理字符串的基本逻辑,是典型 Immutable 类。所有类、属性是 final,拼接、裁剪等动作会产生新 String 对象。
StringBuffer 是为减少中间对象而提供的类,可用 append/add 把添加字符串,线程安全。StringBuilder 非线程安全,其他和 StringBuffer 相同,大部分情况首选。

追问1:String是基本数据类型吗?

不是,String是一个类。

  • 补充
  • 1)整数:byte, short, int, long(分别是8、16、32、64位
  • 2)浮点:double, float
  • 3)逻辑:boolean
  • 4)文本:char

追问2:StringBuffer为什么线程安全?

因为加了synchronized。

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

10、int和Integer有什么区别?【第7讲】(*2):包,自动装箱拆箱、值缓存,较小数值范围

  • 1)int 是 Java 8 个原始数据类型之一。
  • 2)Integer 是 int 的包装类,有 int 字段存储数据,并提供基本操作,如运算、转换等。在Java 5 引入自动装箱和自动拆箱功能(原始类型<=转换=>对象);值缓存(valueOf方法)带来了明显的性能改进。
补充:
1、原始数据类型不是对象。
2、实践发现大部分数据操作都是集中在较小的有限范围,所以引入值缓存,范围:[-128-127]

二、参考

1、Java基础:static方法与非static方法的区别
2、Java高级特性入门——泛型、反射和注解
3、java提高篇(九)-----实现多重继承
4、Java 8 默认方法和多继承
5、Java重写和重载的区别
6、JAVA重写和重载
7、Java 重写(Override)与重载(Overload)
8、一篇文章让你彻底了解Java内部类
9、Java内部类和匿名内部类的用法
10、java中的匿名内部类总结
11、ClassNotFoundException和NoClassDefFoundError的区别

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值