Java 进阶面试问题列表个人初步整理答案
面向对象编程理念与核心设计思想
多态性、封装性、内聚、耦合
- 多态:把不同种类的东西当做相同的东西来处理 >
(举个例子:三个箱子,而多态的本质是什么:都是箱子,都可以打开箱子,但是打开箱子的具体动作不同(方法)
- 多态的优点:将各种数据统一的处理,根据对象的不同来选择最合适的方法
继承
- 并不是说面向对象一定有继承,比如
javascript
(但是非常重要的) - 多重继承(Python、C++)
- 多重继承的缺点
- Java 中的继承:extends 单继承 + implements 接口
知道哪些设计模式
- 工厂模式 (Spring 中的依赖注入中的 IoC 容器,BeanFactory 与 ApplicationContext)
- 单例模式 (Spring 中的 Bean 的生命周期 singleton 不同于我们设计模式中的单例模式,前者是容器内单例,而后者是类加载器中单例)
- 策略模式 (SQL 在线审核系统中执行 SQL 语句时,导师提了一个需求,SQL 具体执行的模块单独分离出来,而且可以更换不同的执行策略)
- 接口 A 定义策略
- B、C 类实现该策略
- Context 组合模式 组合接口 A
- 模板模式(Template,典型的是 Spring 中 JDBCTemplate 类,对 JDBC 进行封装)
- JDBCTemplate 中已经封装好 JDBC 的执行顺序,而具体执行的内容 (更新、查询)则交给子类去做
- 小技巧:使用 Callback 回调函数形式可以避免再创建子类
- 适配器模式(Tomcat 中的适配器
CoyoAdapter
: 在 Nio) - 外观模式(Tomcat 中的外观模式,RequestFacade)
- 观察者模式 (Tomcat 容器启动的过程)
- 抽象主题 (Subject)- 具体主题 : 注册、删除、唤醒观察者
- 抽象观察者 (Observer)- 具体观察者
Tomcat 中容器启动过程中
- 谁是观察者 (抽象观察者,LifecycleListener)
- 具体观察者:ServerLifecycleListener
- 抽象 Subject:Lifecycle
- 具体 Subject: StandardServer
- 装饰者模式 (JavaIO 与装饰者)
- 状态模式
- 代理模式
- 责任链模式
- 原型模式
- 迭代器模式
- 组合模式
- 过早优化(在 Effective Java、Java 并发编程模型中都多次提到过过早优化的种种缺点)
- 代码的性能瓶颈寻找问题(还没完成代码之前,如何谈性能)
- 对代码优化可能会提升代码的复杂度,提高 Bug 率
-
不要讲大量时间花费在琐碎的问题上
-
魔法数与字符串(而不是用一个变量去定义,在阿里巴巴编程规范中也有强烈指出该问题)
-
避免那些无用的类(没有意义的类)
-
不要用代码的行数来衡量项目的进度 (代码行数-进度; 重量 - 飞机进度)
-
避免重新造轮子
-
类的数量多,并不代表代码更复杂
常用重构的技巧
- 重复代码提炼 (AOP)
- 冗长方法的分割
- 嵌套条件
思想:将不满足的条件放在前面,并及时跳出方法
class BadExample {
public void someMethod(Object A,Object B){
if (A != null) {
if (B != null) {
//code[1]
}else {
//code[3]
}
}else {
//code[2]
}
}
}
/* ---------------------分割线---------------------- */
class GoodExample {
public void someMethod(Object A,Object B){
if (A == null) {
//code[2]
return;
}
if (B == null) {
//code[3]
return;
}
//code[1]
}
}
分支的合并
class BadExample {
public void someMethod(Object A,Object B){
if (A != null) {
if (B != null) {
//code
}
}
}
}
/* ---------------------分割线---------------------- */
class GoodExample {
public void someMethod(Object A,Object B){
if (A != null && B != null) {
//code
}
}
}
复制代码
- 一次性临时变量
- 过长的参数列表 (Context 上下文)
- 常量提取
- 把方法归类到类中,而不是再类之外单独实现
- 冗长类的拆分
- 将子类中重复的属性、方法提取到父类中(比如模板模式)
SOLID 原则
- 单一功能
- 开闭原则
- 里式替换
- 接口隔离 :多个接口浩宇
- 依赖反转 : 一个方法应该“依赖于抽象而不是一个实例”
KISS、DRY、YAGNI 原则
Java 核心概念
1. 基础类型与封装类型的区别
- 内存分配与占据
- 基础类型的操作是直接由指令来操作
2. final 关键字
- 修饰类 : 类不可被继承
- 修饰方法:方法不可被重写
- 修饰字段 : 字段的值初始化后不可再改变
3. static
- 修饰内部类:
- 修饰方法 : 类方法,不用实例化就可以访问
- 修饰字段 : 类成员变量(所有对象均共享,不用是实例化就可以访问)
- 修饰静态代码块 :类在第一次加载过程中就会执行该代码块,且只执行一次
4. java 中的内部类
- 使用内部类来解决 java 不支持多重继承的缺点(implement 只是解决了部分问题)
- 成员内部类 : 不能存在 static 变量和方法;只有先创建外部类,才能创建内部类,在编译期间内部类就存在一个对外部类的引用
- 静态内部类:不需要先创建外部类就可以直接访问静态内部类。不能使用外部类的任何非 static 修饰的方法与变量
5. StringBuilder 与 StringBuffer 区别
- StringBuffer : 线程安全(方法上使用了 synchronized) JDK1.0
- StringBuilder : 线程不安全 JDK1.5
在 JDK1.5 之后,所有的字符串变量的连接操作(s1 + s2)都会采用
StringBuilder
来实现
6. Java 中的不可变类
- String 与 Integer 包装类
- 如何构建不可变类 : final,private,getter
7. Java 垃圾回收器简述原理
正向代理与反向代理区别
shadowsocks
与nginx
的应用区别- 正向代理是:客户
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于