【面试】Java基础篇(一)

0、问题大纲

一、Java 基础

1.1 Java概念原理

1、谈谈你对Java平台的理解?【第1讲】
 - 追问1:面向过程和面向对象有什么区别?
 - 追问2:Java中为什么要写None Static Method(非静态方法/实例化方法)?
 - 追问3:Java和Python的区别
 - 追问4:Java 高级特性?
 - 追问5:“Java 是解释执行”,这个说法正确吗?

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

3、Java为什么不能多继承?
 - 追问1:如何实现多继承?

4、谈谈接口和抽象类有什么区别?【第13讲】(*35、什么是内部类,什么是匿名内部类?

6、重写和重载的区别。(*2- 追问1:多态含义?

7、Exception和Error有什么区别?【第2讲】:Throwable类;可预料VS不可恢复;可检查+不可检查
 - 追问1:你了解哪些 Error、Exception 或者 RuntimeException?
 - 追问2:NoClassDefFoundError 和 ClassNotFoundException 有什么区别?
 - 追问3:异常处理有哪些原则?

8、谈谈finalfinally、 finalize有什么不同?【第3讲】(*2- 追问1final与immutable相同吗?

9、String、StringBuffer、StringBuilder有什么区别?【第5讲】(*3)不可变,中间对象;线程安全;非线程安全
 - 追问1:String是基本数据类型吗?

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

11、谈谈你知道的设计模式(*2)?【第14讲】
 - 追问1:最常用哪种设计模式?
 - 追问2:单例模式是什么,请手动实现(*3- 追问3:Spring 等框架中使用了哪些模式?动态代理实现原理?

一、Java 基础

1.1 Java概念原理

1、谈谈你对Java平台的理解?【第1讲】

答:

  • 1、相较C语言,Java面向对象,有GC(垃圾收集),不用关心内存分配和回收;
  • 2、JVM(跨平台)、JRE(Java基础运行环境)、JDK(Java开发工具包)
    1)JVM + 【Java类库、某些模块等】= JRE
    2)JRE + 【编译器、诊断等工具】 = JDK

1

  • 3、拓展
    1
    ……
追问1:面向过程和面向对象有什么区别?
角度 面向过程 面向对象
特点 以分步骤解决问题,用方法组织代码 以分类解决问题,用类组织代码。
优点 性能好 工程更加模块化,实现更低耦合和高内聚
缺点 适应性差、可拓展性与可维护性差 类调用需要实例化,开销大
特征 步骤 封装、继承、多态

关系:细节用面向过程解决,整体面向对象把控,相辅相成。

追问2:Java中为什么要写None Static Method(非静态方法/实例化方法)?

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

  • 补充:
角度 Static Method Non Static Method
生命周期 与静态类成员一样,装载进内存会常驻,直至JVM关闭 实例化后才分配内存,必须通过类实例引用,当实例对象被JVM回收后,跟着消失
内存位置 静态方法与静态变量创建后使用同一块内存,连续 存在内存多个地方,离散
效率
线程安全 静态方法(变量)共享代码(数据)段,有并发问题 针对确定对象,没问题
追问3:Java和Python的区别
角度 Java Python
类型 静态类型,变通实现运行时修改 全动态
语法 面向对象 结合函数式编程与面向对象
开发周期 有丰富库,快
执行效率 性能稳定,扩展性好 较差
领域 服务器、Web、安卓 脚本处理、AI、图形图像
追问4:Java 高级特性?
  • 1)泛型:参数化类型,即把数据类型变成一个可变参数。

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

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

追问5:“Java 是解释执行”,这个说法正确吗?

答:不太准确。 Java 的源代码首先通过 Javac 编译成为字节码(bytecode),在运行时,JVM内嵌的解释器将字节码转换成为最终的机器码。

但常见 JVM(如 Hotspot JVM)都提供了 JIT(Just-In-Time)编译器,即动态编译器,能在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。

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,这样很难保证我们能够正确程序处理 OutOfMemoryError。
2. 分布式系统最好使用产品日志,详细地输出到日志系统里,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

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

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

11、谈谈你知道的设计模式(*2)?【第14讲】

类别 应用目标 例子
创建型模式 对对象创建过程的各种问题和解决方案的总结 工厂模式、单例模式、构建器模式、原型模式
结构型模式 针对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验 桥接模式、适配器模式、装饰者模式、代理模式、组合模式、外观模式、享元模式
行为型模式 从类或对象之间交互、职责划分等角度总结的模式 策略模式、解释器模式、命令模式、观察者模式、迭代器模式、模板方法模式、访问者模式

补充:

应用分类 中文 英文
创建型模式 工厂模式 Factory、Abstract Factory
单例模式 Singleton
构建器模式 Builder
原型模式 ProtoType
结构型模式 桥接模式 Bridge
适配器模式) Adapter
装饰者模式 Decorator
代理模式 Proxy
组合模式 Composite
外观模式 Facade
享元模式 Flyweight
行为型模式 策略模式 Strategy
解释器模式 Interpreter
命令模式 Command
观察者模式 Observer
迭代器模式 Iterator
、模板方法模式 Template Method
访问者模式 Visitor
  • 追问1:最常用哪种设计模式?
    答:单例模式,工厂方法,抽象工厂,策略模式,观察者模式,代理模式……

  • 追问2:单例模式是什么,请手动实现(*3)
    ……

  • 追问3:Spring 等框架中使用了哪些模式?动态代理实现原理?
    ……

二、参考

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的区别

猜你喜欢

转载自blog.csdn.net/HeavenDan/article/details/112608970
今日推荐