三天肝完设计模式的面试题,面试再不怕设计模式的问题了!!!(1)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

目录

  • Q1:设计模式有哪些原则?

  • Q2:设计模式的分类,你知道哪些设计模式?

  • Q3:说⼀说简单⼯⼚模式

  • Q4:说⼀说⼯⼚⽅法模式

  • Q5:抽象⼯⼚模式了解吗?

  • Q6:单例模式的特点是什么?

  • Q7:单例模式有哪些实现?

  • Q8:讲⼀讲代理模式

  • Q9:讲⼀讲装饰器模式

  • Q10:装饰器模式和动态代理的区别?

  • Q11:讲⼀讲适配器模式

  • Q12:适配器模式和和装饰器模式以及代理模式的区别?

  • Q13:讲⼀讲策略模式

  • Q14:讲⼀讲模板模式

  • Q15:讲⼀讲观察者模式

Q1:设计模式有哪些原则?

==============================================================================

开闭原则:OOP 中最基础的原则,指⼀个软件实体(类、模块、⽅法等)应该对扩展开放,对修改关闭。强调⽤抽象构建框架,⽤实现扩展细节,提⾼代码的可复⽤性和可维护性。

单⼀职责原则:⼀个类、接⼝或⽅法只负责⼀个职责,降低代码复杂度以及变更引起的⻛险。

依赖倒置原则:程序应该依赖于抽象类或接⼝,⽽不是具体的实现类。

接⼝隔离原则:将不同功能定义在不同接⼝中实现接⼝隔离,避免了类依赖它不需要的接⼝,减少了接⼝之间依赖的冗余性和复杂性。

⾥⽒替换原则:开闭原则的补充,规定了任何⽗类可以出现的地⽅⼦类都⼀定可以出现,可以约束继承 泛滥,加强程序健壮性。

迪⽶特原则:也叫最少知道原则,每个模块对其他模块都要尽可能少地了解和依赖,降低代码耦合度。

合成/聚合原则:尽量使⽤组合(has-a)/聚合(contains-a)⽽不是继承(is-a)达到软件复⽤的⽬的,避免滥

⽤继承带来的⽅法污染和⽅法爆炸,⽅法污染指⽗类的⾏为通过继承传递给⼦类,但⼦类并不具备执

此⾏为的能⼒;⽅法爆炸指继承树不断扩⼤,底层类拥有的⽅法过于繁杂,导致很容易选择错误。

Q2:设计模式的分类,你知道哪些设计模式?

======================================================================================

创建型: 在创建对象的同时隐藏创建逻辑,不使⽤ new 直接实例化对象,程序在判断需要创建哪些对象时更灵活。包括⼯⼚/抽象⼯⼚/单例/建造者/原型模式。

结构型: 通过类和接⼝间的继承和引⽤实现创建复杂结构的对象。包括适配器/桥接模式/过滤器/组合/ 装饰器/外观/享元/代理模式。

⾏为型: 通过类之间不同通信⽅式实现不同⾏为。包括责任链/命名/解释器/迭代器/中介者/备忘录/观察者/状态/策略/模板/访问者模式。

Q3:说⼀说简单⼯⼚模式

=============================================================================

简单⼯⼚模式指由⼀个⼯⼚对象来创建实例,客户端不需要关注创建逻辑,只需提供传⼊⼯⼚的参数。

适⽤于⼯⼚类负责创建对象较少的情况,缺点是如果要增加新产品,就需要修改⼯⼚类的判断逻辑,违背开闭原则,且产品多的话会使⼯⼚类⽐较复杂。

Calendar 抽象类的⽇历对象。⽅法,调⽤⽅法根据不同的地区参数创建不同的Spring 中的 BeanFactory 使⽤简单⼯⼚模式,根据传⼊⼀个唯⼀的标识来获得 Bean 对象。

Q4:说⼀说⼯⼚⽅法模式

=============================================================================

⼯⼚⽅法模式指定义⼀个创建对象的接⼝,让接⼝的实现类决定创建哪种对象,让类的实例化推迟到⼦类中进⾏。

客户端只需关⼼对应⼯⼚⽽⽆需关⼼创建细节,主要解决了产品扩展的问题,在简单⼯⼚模式中如果产品种类变多,⼯⼚的职责会越来越多,不便于维护。

Collection 接⼝这个抽象⼯⼚中定义了⼀个抽象的 ⼯⼚⽅法,返回⼀个 Iterator 类的抽象产

品。该⽅法通过 ArrayList 、HashMap 等具体⼯⼚实现,返回 Itr、KeyIterator 等具体产品。

Spring 的 FactoryBean 接⼝的⽅法也是⼯⼚⽅法。

Q5:抽象⼯⼚模式了解吗?

==============================================================================

抽象⼯⼚模式指提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽆需指定它们的具体类。

客户端不依赖于产品类实例如何被创建和实现的细节,主要⽤于系统的产品有多于⼀个的产品族,⽽系 统只消费其中某⼀个产品族产品的情况。抽象⼯⼚模式的缺点是不⽅便扩展产品族,并且增加了系统的 抽象性和理解难度。

java.sql.Connection 接⼝就是⼀个抽象⼯⼚,其中包括很多抽象产品如 Statement、Blob、Savepoint等。

public class AbstractFactoryTest {

public static void main(String[] args) {

// 抽象工厂

String result = (new CoffeeFactory()).createProduct(“Latte”);

System.out.println(result); // output:拿铁

}

}

// 抽象工厂

abstract class AbstractFactory{

public abstract String createProduct(String product);

}

// 啤酒工厂

class BeerFactory extends AbstractFactory{

@Override

public String createProduct(String product) {

String result = null;

switch (product) {

case “Hans”:

result = “汉斯”;

break;

case “Yanjing”:

result = “燕京”;

break;

default:

result = “其他啤酒”;

break;

}

return result;

}

}

/* * 咖啡工厂 */

class CoffeeFactory extends AbstractFactory{

@Override

public String createProduct(String product) {

String result = null;

switch (product) {

case “Mocca”:

result = “摩卡”;

break;

case “Latte”:

result = “拿铁”;

break;

default:

result = “其他咖啡”;

break;

}

return result;

}

}

Q6:单例模式的特点是什么?

===============================================================================

单例模式属于创建型模式,⼀个单例类在任何情况下都只存在⼀个实例,构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀个静态公有⽅法获取实例。

优点是内存中只有⼀个实例,减少了开销,尤其是频繁创建和销毁实例的情况下并且可以避免对资源的多重占⽤。缺点是没有抽象层,难以扩展,与单⼀职责原则冲突。

Spring 的 ApplicationContext 创建的 Bean 实例都是单例对象,还有 ServletContext、数据库连接池等也都是单例模式。

Q7:单例模式有哪些实现?

==============================================================================

饿汉式:在类加载时就初始化创建单例对象,线程安全,但不管是否使⽤都创建对象可能会浪费内存。

懒汉式:在外部调⽤时才会加载,线程不安全,可以加锁保证线程安全但效率低。

双重检查锁:使⽤ volatile 以及多重检查来减⼩锁范围,提升效率。

静态内部类:同时解决饿汉式的内存浪费问题和懒汉式的线程安全问题。

枚举:《Effective Java》提倡的⽅式,不仅能避免线程安全问题,还能防⽌反序列化重新创建新的对象,绝对防⽌多次实例化,也能防⽌反射破解单例的问题。

Q8:讲⼀讲代理模式

===========================================================================

代理模式属于结构型模式,为其他对象提供⼀种代理以控制对这个对象的访问。优点是可以增强⽬标对 象的功能,降低代码耦合度,扩展性好。缺点是在客户端和⽬标对象之间增加代理对象会导致请求处理速度变慢,增加系统复杂度。

Spring 利⽤动态代理实现 AOP,如果 Bean 实现了接⼝就使⽤ JDK 代理,否则使⽤ CGLib 代理。

静态代理:代理对象持有被代理对象的引⽤,调⽤代理对象⽅法时也会调⽤被代理对象的⽅法,但是会 在被代理对象⽅法的前后增加其他逻辑。需要⼿动完成,在程序运⾏前就已经存在代理类的字节码⽂件,代理类和被代理类的关系在运⾏前就已经确定了。 缺点是⼀个代理类只能为⼀个⽬标服务,如果要服务多种类型会增加⼯作量。

动态代理:动态代理在程序运⾏时通过反射创建具体的代理类,代理类和被代理类的关系在运⾏前是不确定的。动态代理的适⽤性更强,主要分为 JDK 动态代理和 CGLib 动态代理。

JDK 动态代理:通过类的⽅法获取⼀个动态代理对象,需要传⼊三个参数,被代理对象的类加载器、被代理对象实现的接⼝,以及⼀个器来指明具体的逻辑,相⽐静态代理的优势是接⼝中声明的所有⽅法都被转移到调⽤处理的⽅法集中处理。

CGLib 动态代理:JDK 动态代理要求实现被代理对象的接⼝,⽽ CGLib 要求继承被代理对象,如果⼀个类是 final 类则不能使⽤ CGLib 代理。两种代理都在运⾏期⽣成字节码,JDK 动态代理直接写字节码,⽽ CGLib 动态代理使⽤ ASM 框架写字节码,ASM 的⽬的是⽣成、转换和分析以字节数组表示的已编译 Java 类。 JDK 动态代理调⽤代理⽅法通过反射机制实现,⽽ GCLib 动态代理通过 FastClass 机制直接调⽤⽅法,它为代理类和被代理类各⽣成⼀个类,该类为代理类和被代理类的⽅法分配⼀个 int 参数,调⽤⽅法时可以直接定位,因此调⽤效率更⾼。

Q9:讲⼀讲装饰器模式

============================================================================

装饰器模式属于结构型模式,在不改变原有对象的基础上将功能附加到对象,相⽐继承可以更加灵活地 扩展原有对象的功能。

装饰器模式适合的场景:在不想增加很多⼦类的前提下扩展⼀个类的功能。

java.io 包中,InputStream 字节输⼊流通过装饰器 BufferedInputStream 增强为缓冲字节输⼊流。

Q10:装饰器模式和动态代理的区别?

===================================================================================

装饰器模式的关注点在于给对象动态添加⽅法,⽽动态代理更注重对象的访问控制。动态代理通常会在 代理类中创建被代理对象的实例,⽽装饰器模式会将装饰者作为构造⽅法的参数。

Q11:讲⼀讲适配器模式

=============================================================================

适配器模式属于结构型模式,它作为两个不兼容接⼝之间的桥梁,结合了两个独⽴接⼝的功能,将⼀个 类的接⼝转换成另外⼀个接⼝使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。

缺点是过多使⽤适配器会让系统⾮常混乱,不易整体把握。

java.io 包中,InputStream 字节输⼊流通过适配器 InputStreamReader 转换为 Reader 字符输⼊流。

Spring MVC 中的 HandlerAdapter,由于 handler 有很多种形式,包括 Controller、HttpRequestHandler、Servlet 等,但调⽤⽅式⼜是确定的,因此需要适配器来进⾏处理,根据适配规则调⽤ handle ⽅法。

Arrays.asList ⽅法,将数组转换为对应的集合(注意不能使⽤修改集合的⽅法,因为返回的 ArrayList

是 Arrays 的⼀个内部类)。

适配器实现的代码如下:

/* * 传统的充电线 MicroUSB */

interface MicroUSB {

void charger();

}

/* * TypeC 充电口 */

interface ITypeC {

void charger();

}

class TypeC implements ITypeC {

@Override

public void charger() {

System.out.println(“TypeC 充电”);

}

}

/* * 适配器 */

class AdapterMicroUSB implements MicroUSB {

private TypeC typeC;

最后的内容

在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)

如何准备面试?

1、前期铺垫(技术沉积)

程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。

下面是我会看的一些资料笔记,希望能帮助大家由浅入深,由点到面的学习Java,应对大厂面试官的灵魂追问

这部分内容过多,小编只贴出部分内容展示给大家了,见谅见谅!

  • Java程序员必看《Java开发核心笔记(华山版)》

  • Redis学习笔记

  • Java并发编程学习笔记

四部分,详细拆分并发编程——并发编程+模式篇+应用篇+原理篇

  • Java程序员必看书籍《深入理解 ava虚拟机第3版》(pdf版)

  • 大厂面试必问——数据结构与算法汇集笔记

其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。

2、狂刷面试题

技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。

①大厂高频45道笔试题(智商题)

②BAT大厂面试总结(部分内容截图)

③面试总结

3、结合实际,修改简历

程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:

以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
你参考参考,如果还不够,那下面这些简历模板任你挑选:

[外链图片转存中…(img-KWPksnWh-1713444159496)]

以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-eg6MJfIP-1713444159496)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值